前台
/pages/find/moments/moments.vue
<template> <view> <free-transparent-bar :scrollTop="scrollTop" @clickRight="clickRight"></free-transparent-bar> <view class="position-relative" style="height: 620rpx;"> <image src="https://douyinzcmcss.oss-cn-shenzhen.aliyuncs.com/shengchengqi/datapic/1.jpg" mode="aspectFill" style="height: 590rpx;" class="bg-secondary w-100"></image> <image :src="avatar" style="width: 120rpx;height:120rpx;right: 30rpx;" mode="" class="bg-secondary rounded position-absolute bottom-0"></image> <text class="text-white font-md position-absolute" style="bottom: 45rpx;right: 160rpx">{{nickname}}</text> </view> <!-- 朋友圈列表样式 --> <free-moment-list v-for="(item,index) in list" :key='index' :item="item" :index="index" @action="doAction" @reply="replyEvent"></free-moment-list> <!-- 评论框 --> <free-popup ref="action" bottom transformOrigin="center bottom"> <view style="height: 105rpx;" class="bg-light border-top flex align-center"> <textarea fixed class="bg-white rounded p-2 font-md" style="height: 45rpx;width: 420rpx;" value="" placeholder="" v-model="content" :focus="true"/> <free-icon-button @click="changeFaceModeal"><text class="iconfont font-lg"></text></free-icon-button> <free-main-button name="发送" :disabled="content.length===0" @click="send"></free-main-button> </view> <!-- 表情包 --> <scroll-view v-if="faceModal" scroll-y="true" style="height: 350rpx;" class="bg-light"> <view class="flex flex-wrap"> <view class="flex align-center justify-center" hover-class="bg-white" style="width:107rpx;height:107rpx;" v-for="(item,index) in faceList" :key="index" @click="addFace(item)"> <text>{{item}}</text> </view> </view> </scroll-view> </free-popup> <!-- 上拉加载 --> <view class="flex align-center justify-center py-5 bg-light" v-if="list.length >= 10"> <text class="text-muted font">{{loadmore}}</text> </view> </view> </template> <script> import freeTransparentBar from '@/components/free-ui/free-transparent-bar.vue'; import freeMomentList from '@/components/free-ui/free-moment-list.vue'; import freePopup from '@/components/free-ui/free-popup.vue'; import freeIconButton from '@/components/free-ui/free-icon-button.vue'; import freeMainButton from '@/components/free-ui/free-main-button.vue'; import $H from '@/common/free-lib/request.js'; import { mapState } from 'vuex'; export default { components:{ freeTransparentBar, freeMomentList, freePopup, freeIconButton, freeMainButton }, data() { return { content:'', scrollTop:0, faceModal:false, faceList:["😀","😁","😂","😃","😄","😅","😆","😉","😊","😋","😎","😍","😘","😗","😙","😚","😇","😐","😑","😶","😏","😣","😥","😮","😯","😪","😫","😴","😌","😛","😜","😝","😒","😓","😔","😕","😲","😷","😖","😞","😟","😤","😢","😭","😦","😧","😨","😬","😰","😱","😳","😵","😡","😠"], commentIndex:-1, page:1, loadmore:'上拉加载更多', key:'moment_timeline', list:[], params:'', reply_user:false } }, onPageScroll(e) { this.scrollTop = e.scrollTop; }, onReachBottom() { if(this.loadmore !== '上拉加载更多'){ return; } this.page += 1; this.loadmore = '加载中...'; this.getData().catch(err=>{ this.page -= 1; uni.showToast({ title:'加载失败', icon:'none' }); this.loadmore = '上拉加载更多'; }) }, onLoad(e) { if(e.key){ this.key = e.key; } if(e.params){ this.params = JSON.parse(decodeURIComponent(e.params)); } this.page = 1; this.getData(); uni.$on('momentNotice',this.momentNotice) }, destroyed() { uni.$off('momentNotice',this.momentNotice) }, onPullDownRefresh() { this.page = 1; this.getData().then(res=>{ uni.showToast({ title:'刷新成功', icon:'none' }); uni.stopPullDownRefresh(); }).catch(err=>{ uni.showToast({ title:'刷新失败', icon:'none' }); uni.stopPullDownRefresh(); }); }, computed:{ ...mapState({ user:state=>state.user.user }), nickname(){ if(!this.params){ return user.nickname || user.username; } return this.params.name; }, avatar(){ let avatar = ''; if(!this.params){ avatar = this.user.avatar; }else{ avatar = this.params.avatar } return avatar || '/static/images/demo/demo6.jpg'; } }, methods: { momentNotice(e){ this.page = 1; this.getData().then(res=>{ uni.showToast({ title:'刷新成功', icon:'none' }); }); }, // 点击操作菜单 doAction(e){ uni.showActionSheet({ itemList: ['点赞','评论'], success: res => { if(res.tapIndex === 0){ // 点赞 this.doSupport(e) }else{ this.content=''; this.faceModal=false; this.commentIndex = e.index; this.reply_user = false; this.$refs.action.show(); // this.doComment(e) } } }); }, // 获取数据 getData(){ return new Promise((result,reject)=>{ let page = this.page; let params = this.key === ''; if(this.params && this.key == 'moment'){ params = '?user_id='+this.params.id; } $H.get(`/${this.key}/${this.page}${param}`).then(res=>{ this.list = page === 1 ? res : [...this.list,...res]; this.loadmore = this.list.length === (page * 10) ? '上拉加载更多' : '没有更多了' result(res); }).catch(err=>{ reject(err); }) }) }, // 点赞 doSupport(e){ $H.post('/moment/like',{id:e.item.moment_id}).then(res=>{ let i = e.item.likes.findIndex(item=>item.id === this.user.id); if(i !== -1){ // 取消点赞 e.item.likes.splice(i,1); }else{ // 点赞 e.item.likes.push({ id:this.user.id, name:this.user.nickname || this.user.username }) } uni.showToast({ title:i !== -1 ? '取消点赞成功' : '点赞成功', icon:'none' }); }) }, // 添加表情 addFace(item){ this.content += item; }, // 开启关闭表情包面板 changeFaceModeal(){ uni.hideKeyboard(); setTimeout(()=>{ this.faceModal = !this.faceModal; },100); }, // 发送 send(){ console.log(this.reply_user); let item = this.list[this.commentIndex]; $H.post('/moment/comment',{ id:item.moment_id, content:this.content, reply_id:this.reply_user ? this.reply_user.id : 0 }).then(res=>{ item.comments.push({ content:this.content, user:{ id:this.user.id, name:this.user.nickname || this.user.username }, replay:this.reply_user ? this.reply : null }) uni.showToast({ title:'评论成功', icon:'none' }) }) this.$refs.action.hide(); }, replyEvent(e){ this.content = ''; this.faceModal = false, this.commentIndex = e.index, this.reply_user = e.reply; this.$refs.action.show(); }, // 选择发表朋友圈类型 clickRight(){ let list = [{ name:'图文', key:'image' }, { name:'视频', key:'video' }, { name:'文字', key:'content' }]; uni.showActionSheet({ itemList:list.map(v=>v.name), success:res=>{ uni.navigateTo({ url: '../add-moment/add-moment?type='+list[res.tapIndex].key, }); } }) } }, } </script> <style> </style>
/pages/mail/user-base/user-base.vue
<template> <view class="page"> <!-- 导航栏 --> <free-nav-bar showBack :showRight="detail.friend" bgColor="bg-white"> <view slot="right"> <free-icon-button v-if="detail.friend"><text class="iconfont font-md" @click="openAction"></text></free-icon-button> </view> </free-nav-bar> <view class="px-3 py-4 flex align-center bg-white border-bottom"> <free-avatar :src="detail.avatar" size="120"></free-avatar> <view class="flex flex-column ml-3 flex-1"> <view class="font-lg font-weight-bold flex justify-between"> <text class="font-lg font-weight-bold mb-1">{{detail.nickname}}</text> <image v-if="detail.star" src="/static/images/star.png" style="width: 40rpx;height: 40rpx;"></image> </view> <text class="font-md text-light-muted mb-1">账号:{{detail.username}}</text> <!-- <text class="font-md text-light-muted">地区:广东广州</text> --> </view> </view> <free-list-item v-if="detail.friend" showRight :showLeftIcon="false" @click="navigate(tagPath)"> <view class="flex align-center"> <text class="font-md text-dark mr-3">标签</text> <text class="font-md text-light-muted mr-2" v-for="(item,index) in detail.tags" :key="index">{{item}}</text> </view> </free-list-item> <free-divider></free-divider> <free-list-item v-if="detail.friend" showRight :showLeftIcon="false" @click="openMoments"> <view class="flex align-center"> <text class="font-md text-dark mr-3">朋友圈</text> <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image> <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image> <image src="/static/images/demo/cate_01.png" style="width: 90rpx; height: 90rpx;" class=" mr-2"></image> </view> </free-list-item> <free-list-item title="更多信息" showRight :showLeftIcon="false"></free-list-item> <free-divider></free-divider> <view v-if="detail.friend" class="py-3 flex align-center justify-center bg-white" hover-class="bg-light" @click="doEvent"> <text class="iconfont text-primary mr-1" v-if="!detail.isBlack"></text> <text class="font-md text-primary">{{detail.isblack ? '移除黑名单' : '发信息'}}</text> </view> <view v-else class="py-3 flex align-center justify-center bg-white" hover-class="bg-light" @click="navigate(addFriend())"> <text class="font-md text-primary">添加好友</text> </view> <!-- 扩展菜单 --> <free-popup ref="action" bottom transformOrigin="center bottom" maskColor> <scroll-view style="height: 580rpx;" scroll-y="true" class="bg-white" :show-scrollbar="false"> <free-list-item v-for="(item,index) in actions" :key="index" :title="item.title" :showRight="false" :border="false" @click="popupEvent(item)"> <text slot="icon" class="iconfont font-lg py-1">{{item.icon}}</text> </free-list-item> </scroll-view> </free-popup> </view> </template> <script> import freeNavBar from '@/components/free-ui/free-nav-bar.vue'; import freeIconButton from '@/components/free-ui/free-icon-button.vue'; import freeChatItem from '@/components/free-ui/free-chat-item.vue'; import freePopup from '@/components/free-ui/free-popup.vue'; import freeListItem from '@/components/free-ui/free-list-item.vue'; import freeDivider from '@/components/free-ui/free-divider.vue'; import freeAvatar from '@/components/free-ui/free-avatar.vue'; import auth from '@/common/mixin/auth.js'; import $H from '@/common/free-lib/request.js'; export default { mixins: [auth], components: { freeNavBar, freeIconButton, freeChatItem, freePopup, freeListItem, freeDivider, freeAvatar }, data() { return { detail: { id: 0, username: '', nickname: '', avatar: '', sex: '', sign: '', area: '', friend: false, lookhim: 1, lookme: 1, star: 0, isblack: 0, tags: [] }, } }, onShow() { this.getData(); }, onLoad(e) { uni.$on('saveRemarkTag', (e) => { this.detail.tagList = e.detail.tagList this.nickname = e.nickname; }) if (!e.user_id) { return this.backToast(); } this.detail.id = e.user_id; // 获取当前用户资料 this.getData(); }, beforeDestroy() { this.$refs.action.hide(); uni.$off('saveRemarkTag') }, computed: { tagPath() { return "mail/user-remark-tag/user-remark-tag?params="+JSON.stringify({ user_id:this.detail.id, nickname:this.detail.nickname, tags:this.detail.tags ? this.detail.tags.join(',') : '' }) }, actions() { return [{ icon: "\ue6b3", title: "设置备注和标签", type: "navigate", path: "mail/user-remark-tag/user-remark-tag?params="+JSON.stringify({ user_id:this.detail.id, nickname:this.detail.nickname, tags:this.detail.tags ? this.detail.tags.join(',') : '' }) }, { icon: "\ue613", title: "把他推荐给朋友", type: "navigate", path: "chat/chat-list/chat-list?params="+encodeURIComponent(JSON.stringify({ type: "card", data: this.detail.nickname || this.detail.username, options: { avatar: this.detail.avatar, id: this.detail.id } })) }, { icon: "\ue6b0", title: this.detail.star ? '取消星标好友' : "设为星标朋友", type: "event", event: "setStar" }, { icon: "\ue667", title: "设置朋友圈和动态权限", type: "navigate", path: "mail/user-moments-auth/user-moments-auth?user_id="+this.detail.id+"¶ms="+JSON.stringify({ lookme:this.detail.lookme, lookhim:this.detail.lookhim, }) }, { icon: "\ue638", title: this.detail.isblack ? '移出黑名单' : "加入黑名单", type: "event", event: "setBlack" }, { icon: "\ue61c", title: "投诉", type: "navigate", path: "mail/user-report/user-report?params="+JSON.stringify({ user_id:this.detail.id, type:'user' }) }, { icon: "\ue638", title: "删除", type: "event", event: "deleteItem" }] } }, methods: { addFriend() { let obj = { friend_id: this.detail.id, nickname: this.detail.nickname, lookme: typeof this.detail.lookme === 'number' ? this.detail.lookme : 1, lookhim: typeof this.detail.lookhim === 'number' ? this.detail.lookhim : 1, }; return 'mail/add-friend/add-friend?params=' + JSON.stringify(obj); }, getData() { $H.get('/friend/read/' + this.detail.id).then(res => { if (!res) { return this.backToast('该用户不存在'); } this.detail = res; console.log(res); }); }, openAction() { this.$refs.action.show() }, navigate(url) { console.log(url); uni.navigateTo({ url: '/pages/' + url, }); }, openMoments(){ uni.navigateTo({ url:'../.../find/moments/moments?key=moment¶ms='+encodeURIComponent(JSON.stringify({ id:this.detail.id, name:this.detail.nickname || this.detail.username, avatar:this.detail.avatar })) }) }, // 操作菜单事件 popupEvent(e) { if (!e.type) { return; } setTimeout(() => { // 关闭弹出层 this.$refs.action.hide() }, 300) switch (e.type) { case 'navigate': this.navigate(e.path); break; case 'event': this[e.event](e); break; } }, // 删除好友 deleteItem(){ uni.showModal({ title: '是否要删除好友?', success: res => { if(res.confirm){ $H.post('/friend/destroy',{friend_id:this.detail.id}).then(res=>{ uni.showToast({ title:'删除好友成功', icon:'none' }); uni.reLaunch({ url:'/pages/tabbar/index/index' }) }) } }, fail: () => {}, complete: () => {} }); }, // 设为星标 setStar(e) { let star = this.detail.star == 0 ? 1 : 0; $H.post('/friend/setstar/' + this.detail.id, { star }).then(res => { this.detail.star = star; e.title = this.detail.star ? '取消标星好友' : '设为标星好友'; }); }, // 加入黑名单 setBlack(e) { let msg = this.detail.isblack ? '移出黑名单' : '加入黑名单'; uni.showModal({ content: '是否要' + msg, success: (res) => { if (res.confirm) { let isblack = this.detail.isblack == 0 ? 1:0 $H.post('/friend/setblack/' + this.detail.id, { isblack }).then(res => { this.detail.isblack = isblack; }); // this.detail.isBlack = !this.detail.isBlack; // e.title = this.isBlack ? '移出黑名单' : '加入黑名单'; uni.showToast({ title: msg + '成功', icon: 'none' }) } } }) }, // 发送消息 doEvent(e){ if(this.detail.isblack){ return this.setBlack(); } uni.navigateTo({ url:'../../chat/chat/chat?params='+encodeURIComponent(JSON.stringify({ id:this.detail.id, name:this.detail.nickname ? this.detail.nickname : this.detail.username, avatar:this.detail.avatar, chat_type:'user' })) }) } } } </script> <style> </style>
后台
/app/controller/moment.js
'use strict'; const Controller = require('egg').Controller; class MomentController extends Controller { // 发布朋友圈 async create() { const { ctx, app } = this; let current_user_id = ctx.authUser.id; // 参数验证 ctx.validate({ content: { type: 'string', required: false, desc: '内容' }, image: { type: 'string', required: false, desc: '图片' }, video: { type: 'string', required: false, desc: '视频' }, type: { type: 'string', required: true, range: { in: ['content', 'image', 'video'] }, desc: '朋友圈类型' }, location: { type: 'string', required: false, desc: '位置' }, remind: { type: 'string', required: false, defValue: "", desc: '提醒谁看' }, see: { type: 'string', required: false, defValue: "all", desc: '谁可以看' } }); let { content, image, video, type, location, remind, see } = ctx.request.body; if (!ctx.request.body[type]) { return ctx.apiFail(`${type} 不能为空`); } let moment = await app.model.Moment.create({ content, image, video, location, remind, see, user_id: current_user_id }); if (!moment) { return ctx.apiFail('发布失败'); } // 推送到好友的时间轴 this.toTimeline(moment); ctx.apiSuccess('ok'); } // 推送到好友的时间轴 async toTimeline(moment) { const { ctx, app } = this; let current_user_id = ctx.authUser.id; // 获取当前用户所有好友 let friends = await app.model.Friend.findAll({ where: { user_id: current_user_id, isblack: 0 }, attributes: ['friend_id'] }); // 谁可以看 /** all 全部人可看 only:1,2,3 指定人可见 except:1,2,3 谁不可看 none 仅自己可见 */ let sees = moment.see.split(':'); let o = { only: [], except: [] } let oType = sees[0]; if ((sees[0] === 'only' || sees[0] === 'except') && sees[1]) { o[sees[0]] = (sees[1].split(',')).map(v => parseInt(v)); } let addData = friends.filter(item => { return oType === 'all' || (oType === 'only' && o.only.includes(item.friend_id)) || (oType === 'except' && !o.except.includes(item.friend_id)); }); addData = addData.map(item => { return { user_id: item.friend_id, moment_id: moment.id, own: 0 } }); addData.push({ user_id: current_user_id, moment_id: moment.id, own: 1 }); // 推送到时间轴当中 await app.model.MomentTimeline.bulkCreate(addData); // 消息推送 let message = { avatar: ctx.authUser.avatar, user_id: current_user_id, type: "new" } addData.forEach(item => { ctx.sendAndSaveMessage(item.user_id, message, 'moment'); }); // 提醒用户 if (moment.remind) { let arr = moment.remind.split(','); arr.forEach(user_id => { ctx.sendAndSaveMessage(user_id, { avatar: ctx.authUser.avatar, user_id: current_user_id, type: "remind" }, 'moment'); }); } } // 点赞 async like() { const { ctx, app } = this; let current_user_id = ctx.authUser.id; ctx.validate({ id: { type: "int", required: true, desc: "朋友圈id" } }); let { id } = ctx.request.body; let MomentTimeline = await app.model.MomentTimeline.findOne({ where: { user_id: current_user_id, moment_id: id }, include: [{ model: app.model.Moment, attributes: ['user_id'], include: [{ model: app.model.MomentLike, attributes: ['user_id'], }] }] }); if (!MomentTimeline) { return ctx.apiFail('朋友圈消息不存在'); } let like = await app.model.MomentLike.findOne({ where: { user_id: current_user_id, moment_id: id } }); let message = { avatar: ctx.authUser.avatar, user_id: current_user_id, type: "like" } if (like) { await like.destroy(); ctx.apiSuccess(MomentTimeline.moment.moment_likes); } else { await app.model.MomentLike.create({ user_id: current_user_id, moment_id: id }); ctx.apiSuccess(MomentTimeline.moment.moment_likes); } // 通知作者 if (MomentTimeline.moment.user_id && MomentTimeline.moment.user_id !== current_user_id) { ctx.sendAndSaveMessage(MomentTimeline.moment.user_id, message, 'moment'); } // 通知相关人 MomentTimeline.moment.moment_likes.forEach(item => { if (item.user_id !== current_user_id) { ctx.sendAndSaveMessage(item.user_id, message, 'moment'); } }); } // 朋友圈评论 async comment() { const { ctx, app } = this; let current_user_id = ctx.authUser.id; ctx.validate({ id: { type: "int", required: true, desc: "朋友圈id" }, content: { type: "string", required: true, desc: "评论内容" }, reply_id: { type: "int", required: true, defValue: 0, desc: "回复id" } }); let { id, content, reply_id } = ctx.request.body; let MomentTimeline = await app.model.MomentTimeline.findOne({ where: { user_id: current_user_id, moment_id: id }, include: [{ model: app.model.Moment, attributes: ['user_id'], include: [{ model: app.model.MomentLike, attributes: ['user_id'] }] }] }); if (!MomentTimeline) { return ctx.apiFail('朋友圈消息不存在'); } let comment = await app.model.MomentComment.create({ user_id: current_user_id, moment_id: id, content, reply_id }); ctx.apiSuccess(comment); let message = { avatar: ctx.authUser.avatar, user_id: current_user_id, type: "comment" } // 通知作者 if (MomentTimeline.moment.user_id && MomentTimeline.moment.user_id !== current_user_id) { ctx.sendAndSaveMessage(MomentTimeline.moment.user_id, message, 'moment'); } // 通知相关人 MomentTimeline.moment.moment_likes.forEach(item => { if (item.user_id !== current_user_id) { ctx.sendAndSaveMessage(item.user_id, message, 'moment'); } }); // 通知被回复人 if (reply_id > 0) { let index = MomentTimeline.moment.moment_likes.findIndex(item => { return item.user_id === reply_id }); if (index === -1) { ctx.sendAndSaveMessage(reply_id, message, 'moment'); } } } // 朋友圈列表 async timeline() { const { ctx, app } = this; let current_user_id = ctx.authUser.id; let page = ctx.params.page ? parseInt(ctx.params.page) : 1; let limit = ctx.query.limit ? parseInt(ctx.query.limit) : 10; let offset = (page - 1) * limit; let rows = await app.model.MomentTimeline.findAll({ where: { user_id: current_user_id }, include: [{ model: app.model.Moment, include: [{ model: app.model.User, attributes: ['id', 'nickname', 'username', 'avatar'] }, { model: app.model.MomentComment, attributes: { exclude: ['created_at', 'updated_at'] }, include: [{ model: app.model.User, as: "momentCommentUser", attributes: ['id', 'nickname', 'username'] }, { model: app.model.User, as: "momentCommentReply", attributes: ['id', 'nickname', 'username'] }] }, { model: app.model.MomentLike, attributes: ['user_id', 'moment_id'], include: [{ model: app.model.User, attributes: ['id', 'nickname', 'username'] }] }] }], offset, limit, order: [ ['id', 'DESC'] ] }); let friends = await app.model.Friend.findAll({ where: { user_id: current_user_id, lookhim: 1 }, attributes: ['friend_id'] }); console.log(friends); let bfriends = await app.model.Friend.findAll({ where: { friend_id: current_user_id, lookme: 1 }, attributes: ['user_id'] }); friends = friends.map(item => item.friend_id); bfriends = bfriends.map(item => item.user_id); friends = friends.filter(item => bfriends.includes(item)); let res = []; rows.forEach(item => { if (friends.includes(item.moment.user_id) || item.moment.user_id === current_user_id) { let comments = []; item.moment.moment_comments.forEach(v => { if (friends.includes(v.momentCommentUser.id) || v.momentCommentUser.id === current_user_id) { comments.push({ content: v.content, user: { id: v.momentCommentUser.id, name: v.momentCommentUser.nickname || v.momentCommentUser.username }, reply: v.momentCommentReply ? { id: v.momentCommentReply.id, name: v.momentCommentReply.nickname || v.momentCommentReply.username } : null }); } }); let likes = []; item.moment.moment_likes.forEach(v => { if (friends.includes(v.user.id) || v.user.id === current_user_id) { likes.push({ id: v.user.id, name: v.user.nickname || v.user.username }); } }); res.push({ id: item.id, user_id: item.moment.user_id, user_name: item.moment.user.nickname || item.moment.user.username, avatar: item.moment.user.avatar, moment_id: item.moment_id, content: item.moment.content, image: item.moment.image ? item.moment.image.split(',') : [], video: item.moment.video ? JSON.parse(item.moment.video) : null, location: item.moment.location, own: item.own, created_at: item.created_at, comments, likes }); } }); ctx.apiSuccess(res); } // 某个用户的朋友圈列表 async list() { const { ctx, app } = this; let current_user_id = ctx.authUser.id; let page = ctx.params.page ? parseInt(ctx.params.page) : 1; let limit = ctx.query.limit ? parseInt(ctx.query.limit) : 10; let offset = (page - 1) * limit; let user_id = ctx.query.user_id ? parseInt(ctx.query.user_id) : 0; // ctx.validate({ // user_id: { // type: "int", // required: false, // defValue: current_user_id, // desc: "用户id" // } // }); let lookIds = []; if (!user_id) { // 本人 user_id = current_user_id; lookIds = false; } else { // 验证我是否具备权限 是否是朋友,是否拉黑,是否删除 let f = await app.model.User.findOne({ where: { id: user_id, status: 1 }, attributes: ['id', 'nickname', 'username', 'avatar'], include: [{ model: app.model.Friend, as: "bfriends", where: { user_id: current_user_id }, attributes: ['lookhim', 'isblack'] }, { model: app.model.Friend, as: "friends", where: { friend_id: current_user_id }, attributes: ['lookme', 'isblack'] }] }); // 用户是否存在 if (!f) { return ctx.apiFail('用户不存在或已被禁用'); } // 是否是好友关系 if (!f.bfriends.length || !f.friends.length) { return ctx.apiSuccess([]); } // 不可见 if (f.bfriends[0].isblack || f.friends[0].isblack || !f.bfriends[0].lookhim || !f.friends[0].lookme) { return ctx.apiSuccess([]); } // 获取当前用户所有好友(查找共同好友) let friends = await app.model.Friend.findAll({ where: { user_id: current_user_id, isblack: 0 }, attributes: ['friend_id'] }); lookIds = friends.map(item => item.friend_id); } let rows = await app.model.Moment.findAll({ where: { user_id }, include: [{ model: app.model.User, attributes: ['id', 'nickname', 'username', 'avatar'] }, { model: app.model.MomentComment, attributes: { exclude: ['created_at', 'updated_at'] }, include: [{ model: app.model.User, as: "momentCommentUser", attributes: ['id', 'nickname', 'username'] }, { model: app.model.User, as: "momentCommentReply", attributes: ['id', 'nickname', 'username'] }] }, { model: app.model.MomentLike, attributes: ['user_id', 'moment_id'], include: [{ model: app.model.User, attributes: ['id', 'nickname', 'username'] }] }], offset, limit, order: [ ['id', 'DESC'] ] }); let res = []; rows.forEach(item => { let comments = []; item.moment_comments.forEach(v => { if (!lookIds || lookIds.includes(v.momentCommentUser.id) || v.momentCommentUser.id === current_user_id) { comments.push({ content: v.content, user: { id: v.momentCommentUser.id, name: v.momentCommentUser.nickname || v.momentCommentUser.username }, reply: v.momentCommentReply ? { id: v.momentCommentReply.id, name: v.momentCommentReply.nickname || v.momentCommentReply.username } : null }) } }); let likes = []; item.moment_likes.forEach(v => { if (!lookIds || lookIds.includes(v.user.id) || v.user.id === current_user_id) { likes.push({ id: v.user.id, name: v.user.nickname || v.user.username }); } }); res.push({ user_id: item.user_id, user_name: item.user.nickname || item.user.username, avatar: item.user.avatar, moment_id: item.id, content: item.content, image: item.image ? item.image.split(',') : [], video: item.video ? JSON.parse(item.video) : null, location: item.location, own: 1, created_at: item.created_at, comments, likes }); }); ctx.apiSuccess(res); } } module.exports = MomentController;
感谢大家观看,我们下次见