circle.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. <template>
  2. <view id="moments" class="page">
  3. <view class="home-pic">
  4. <image :src="photo(my_data.circle_img)" @tap="upload" style="width: 100vw;height:65vw;"></image>
  5. <view class="home-pic-base">
  6. <view class="top-pic">
  7. <image class="header" :src="image_cache(myPhoto)" @tap.stop="goDetails(my_data.id)" :lazy-load="true" />
  8. </view>
  9. <view class="top-name">{{ my_data.nickname }}</view>
  10. </view>
  11. </view>
  12. <view class="new_msg" style="color: #333333;" @tap="goCircleChat" v-if="no_reader_msg">你有<view style="color: #ff0000;display: inline;">{{no_reader_msg}}条</view>新的消息</view>
  13. <view class="moments__post1" v-for="(post,index) in posts" :key="index" :id="'post-'+index">
  14. <view class="moments__post">
  15. <view class="post-left">
  16. <image class="post_header" :src="image_cache(post.header_image)" @tap="goDetails(post.userid)" :lazy-load="true"/>
  17. </view>
  18. <view class="post_right">
  19. <view class="post-username" @tap="goDetails(post.uid)">{{post.username}}</view>
  20. <view id="paragraph" class="paragraph" @tap="init_input()">{{post.content.text}}</view>
  21. <!-- 相册 -->
  22. <view class="thumbnails" v-if="post.type == 0" @tap="init_input()">
  23. <view :class="post.content.value.length === 1 ? 'my-gallery' : 'thumbnail' "
  24. v-for="(image, index_images) in post.content.value"
  25. :key="index_images">
  26. <image class="gallery_img"
  27. :lazy-load="true"
  28. mode="aspectFill"
  29. :src="image_cache(staticPath + image)"
  30. :data-src="image"
  31. @tap="previewImage(index,index_images)"
  32. />
  33. </view>
  34. </view>
  35. <!-- 资料条 -->
  36. <view class="toolbar">
  37. <view class="timestamp">{{ post.timestamp }}
  38. <view class="delete" v-if="post.userid==myid" @tap="circle_delete(index)">删除</view>
  39. </view>
  40. <view class="like" @tap="like(index)">
  41. <image :src="post.islike === 0 ? '../../static/push/circle/islike.png' : '../../static/push/circle/like.png'" :lazy-load="true"/>
  42. </view>
  43. <view class="comment" @tap="comment(index)">
  44. <image src="../../static/push/circle/comment.png" :lazy-load="true"></image>
  45. </view>
  46. </view>
  47. <!-- 赞/评论区 -->
  48. <view class="post-footer">
  49. <view class="footer_content" v-if="post.like.length">
  50. <image class="liked" src="../../static/push/circle/liked.png" :lazy-load="true"></image>
  51. <view class="nickname"
  52. v-for="(user,index_like) in post.like"
  53. :key="index_like"
  54. @tap="goDetails(user.uid)"
  55. >
  56. {{(index_like ? ',' : '' ) + user.username}}
  57. </view>
  58. </view>
  59. <view class="footer_content"
  60. v-for="(comment,comment_index) in post.comment"
  61. :key="comment_index"
  62. @tap="reply(index,comment_index)">
  63. <view class="comment-nickname" style="word-break:break-all;line-height: 40upx;">
  64. {{comment.username + comment.reply + ': '}}
  65. <text class="comment-content">
  66. {{comment.content}}
  67. </text>
  68. <view class="delete" style="float: right;" v-if="comment.uid==myid" @tap="comment_delete(index,comment_index)">删除</view>
  69. </view>
  70. </view>
  71. </view>
  72. </view>
  73. </view>
  74. <!-- 结束 post -->
  75. </view>
  76. <view class="foot" style="z-index: 999999;" v-show="showInput">
  77. <chat-input @send-message="send_comment" @blur="blur" :focus="focus" :placeholder="input_placeholder"></chat-input>
  78. <!-- <chat-input @send-message="send_comment" @blur="blur" :placeholder="input_placeholder"></chat-input> -->
  79. </view>
  80. <view class="loadmore" v-if="showLoadMore">{{loadMoreText}}</view>
  81. </view>
  82. </template>
  83. <script>
  84. import {
  85. mapState
  86. } from 'vuex';
  87. import chatInput from './circle/chat_input.vue'; //输入消息框
  88. import _data from "../../library/_data.js"
  89. import api from "../../library/index.js"
  90. import action from "../../library/action.js"
  91. import config from "../../config.js"
  92. import helper from "../../library/helper.js"
  93. export default {
  94. components: {
  95. chatInput
  96. },
  97. data() {
  98. return {
  99. my_data: {
  100. },
  101. user_id: 0,
  102. posts:[],
  103. index: '',
  104. comment_index: '',
  105. input_placeholder: '评论', //占位内容
  106. focus: false, //是否自动聚焦输入框
  107. is_reply: false, //回复还是评论
  108. showInput: false, //评论输入框
  109. screenHeight: '', //屏幕高度(系统)
  110. platform: '',
  111. windowHeight: '' ,//可用窗口高度(不计入软键盘)
  112. loadMoreText: "加载中...",
  113. showLoadMore: false,
  114. is_more: false,
  115. no_reader_msg: uni.getStorageSync('data_circle_tips')?uni.getStorageSync('data_circle_tips'):0,
  116. loaddata:[],
  117. myid:uni.getStorageSync('access_token'),
  118. userinfo:uni.getStorageInfoSync('userInfo'),
  119. page:1,
  120. }
  121. },
  122. created() {
  123. this.my_data= {
  124. id: uni.getStorageSync('access_token'),
  125. nickname: this.userinfo.nickname,
  126. photo: '../../static/logo.png',
  127. circle_img: '../../static/img/default_circle_img.jpg',
  128. }
  129. },
  130. computed:{
  131. myPhoto(){
  132. return this.my_data.photo ;
  133. },
  134. circleImg(){
  135. return this.my_data.circle_img;
  136. },
  137. staticPath(){
  138. return config.imgUri;
  139. },
  140. imgRan(){
  141. return Math.random();
  142. },
  143. },
  144. onLoad(option) {
  145. // let _this = this;
  146. // uni.getSystemInfo({ //获取设备信息
  147. // success: (res) => {
  148. // _this.screenHeight = res.screenHeight;
  149. // _this.platform = res.platform;
  150. // }
  151. // });
  152. //this.onGetData();
  153. this.onshowlisten();
  154. },
  155. onShow() {
  156. var _this = this;
  157. this.getUserInfo();
  158. var circle_data =_data.cache('circle_data');
  159. // console.log('onshow');
  160. /** 加载本地缓存数据,让页面秒速渲染出来 */
  161. if(circle_data){
  162. setTimeout(function(){_this.setCircleData(circle_data);},10);
  163. _this.pullDownRefresh();
  164. }
  165. else{
  166. _this.setCircleData([]);
  167. _this.pullDownRefresh();
  168. }
  169. console.log('+++');
  170. },
  171. onUnload() {
  172. this.$socket.off('data_circle_tips');
  173. this.$socket.off('circle_push');
  174. uni.offWindowResize(); //取消监听窗口尺寸变化
  175. this.max = 0,
  176. this.data = [],
  177. this.loadMoreText = "加载更多",
  178. this.showLoadMore = false;
  179. },
  180. onReachBottom() { //监听上拉触底事件
  181. let _this =this;
  182. _this.showLoadMore = true;
  183. if(_this.is_more){
  184. return;
  185. }
  186. this.page++;
  187. this.onGetData();
  188. },
  189. onPullDownRefresh() { //监听下拉刷新动作
  190. if(_data.data('no_reader_circle') || _data.data('no_reader_circle_chat_num')){
  191. this.posts = [];
  192. _data.data('circle_data',[]);
  193. }
  194. this.pullDownRefresh();
  195. },
  196. onNavigationBarButtonTap(e) {//监听标题栏点击事件
  197. if (e.index == 0) {
  198. this.navigateTo('./circle/send');
  199. }
  200. },
  201. methods: {
  202. photo(path){
  203. if(path.indexOf('http')<=-1) return path;
  204. else return this.image_cache(path)
  205. },
  206. onshowlisten(){
  207. this.no_reader_msg = uni.getStorageSync('data_circle_tips') ? uni.getStorageSync('data_circle_tips') : 0;
  208. action.setStatusTips();
  209. _data.data('no_reader_circle',0);
  210. // 监听窗口尺寸变化,窗口尺寸不包括底部导航栏
  211. uni.onWindowResize((res) => {
  212. if(this.platform === 'ios'){
  213. this.windowHeight = res.size.windowHeight;
  214. this.adjust();
  215. }else{
  216. if (this.screenHeight - res.size.windowHeight > 60 && this.windowHeight <= res.size.windowHeight) {
  217. this.windowHeight = res.size.windowHeight;
  218. this.adjust();
  219. }
  220. }
  221. });
  222. this.$socket.on('circle_push', (res) => {//更新朋友圈消息
  223. action.circleUpate(res.data);
  224. this.posts =_data.cache('circle_data');
  225. })
  226. /** 监听朋友圈动态提示 */
  227. this.$socket.on('data_circle_tips',function(res){
  228. if(!isNaN(res.data)){
  229. _this.no_reader_msg = res.data;
  230. };
  231. uni.setStorageSync('data_circle_tips',res.data);
  232. action.setStatusTips();
  233. });
  234. },
  235. upload(e){
  236. uni.chooseImage({
  237. success: (chooseImageRes) => {
  238. uni.showLoading();
  239. const tempFilePaths = chooseImageRes.tempFilePaths;
  240. helper.uploadFiles(tempFilePaths,'image',{type:'avatar'}).then(res=>{
  241. this.my_data.circle_img= res;
  242. // console.log(res);
  243. var avatar= res.replace(config.imgUri,'');
  244. api.changeProfile({circle_img:avatar,id:this.my_data.id}).then(res => {
  245. uni.hideLoading()
  246. this.$toast('更新成功').then(() => {
  247. });
  248. });
  249. })
  250. }
  251. });
  252. },
  253. onGetData(){
  254. let time = 0;
  255. let circle_data11 = _data.localData('circle_data');
  256. if(circle_data11.length>0){
  257. time = circle_data11[0].time;
  258. }
  259. let that =this;
  260. // _data.localData('circle_data',[])
  261. api.getCircleList({userid:uni.getStorageSync('access_token'),page:this.page}).then(res=>{
  262. if(this.page==1)_data.addData('circle_data',res.data)
  263. // console.log(circle_data);
  264. that.setCircleData(res.data);
  265. // uni.$emit('data_circle_data',circle_data);
  266. if(res.data.length < 10){
  267. this.loadMoreText = '没有更多数据了';
  268. this.is_more = true;
  269. this.showLoadMore=true;
  270. }
  271. })
  272. },
  273. setCircleData(data){
  274. var list11=[];
  275. var len=data.length;
  276. let circle_data11 = _data.localData('circle_data');
  277. if(circle_data11.length>0 && this.page>1){
  278. var time = circle_data11[circle_data11.length-1].time;
  279. }
  280. // if(len>20) len=20;
  281. for(var i=0;i<len;i++){
  282. var item=data[i];
  283. if(item.like==false) item.like=[];
  284. if(item.comment==false) item.comment=[];
  285. item.timestamp=action.timestampFormat(item.time);
  286. item.islike=this.setisLike(uni.getStorageSync('access_token'),item.like);
  287. if(item.time<time || this.page==1) list11.push(item);
  288. }
  289. if(this.page==1) {
  290. this.posts=list11;
  291. }
  292. else this.posts.push(...list11);
  293. },
  294. setisLike(id,data){
  295. if(data.length==0 || data==[]) return 0;
  296. for(var i=0;i<data.length;i++){
  297. if(data[i].uid==id) return 1;
  298. }
  299. return 0;
  300. },
  301. goCircleChat(){
  302. _data.data('no_reader_circle_chat_num',0);
  303. this.navigateTo('./circle_chat_details');
  304. },
  305. getUserInfo(){
  306. let _this=this;
  307. api.getUserInfo({friend_uid:uni.getStorageSync('access_token')}).then(res=>{
  308. _this.my_data.id=res.data.id;
  309. _this.my_data.nickname=res.data.nickname;
  310. var photo=res.data.avatar;
  311. if(photo.indexOf('http')<=-1)photo=config.imgUri+photo;
  312. _this.my_data.photo=photo;
  313. if(res.data.circle_img!=null){
  314. this.my_data.circle_img=this.image_cache(res.data.circle_img);
  315. }
  316. })
  317. },
  318. pullDownRefresh() {
  319. var _this = this;
  320. //初始化数据
  321. // this.onGetData();
  322. setTimeout(function(){_this.onGetData();},100);
  323. uni.stopPullDownRefresh(); //停止下拉刷新
  324. /** 取消好友动态提示 */
  325. _data.data('no_reader_circle',0);
  326. },
  327. goDetails(user_id){
  328. this.navigateTo('../friend/detail?id=' + user_id);
  329. },
  330. navigateTo(url) {
  331. uni.navigateTo({
  332. url: url
  333. });
  334. },
  335. socket_push(id,action,userid,issend){
  336. let data={
  337. type:'circle_push',
  338. id:id,
  339. action:action,
  340. fromid:uni.getStorageSync('access_token'),
  341. userid:userid,
  342. issend:issend
  343. }
  344. this.$socket.send(data);
  345. },
  346. circle_delete(index){
  347. let _this = this
  348. uni.showModal({
  349. title: '提示',
  350. content: '确定要删除吗?',
  351. showCancel: true,
  352. cancelText: '取消',
  353. confirmText: '删除',
  354. success: res => {
  355. if(res.confirm) {
  356. var id=_this.posts[index].id;
  357. api.CircleDelete({id:id}).then(res=>{
  358. if(res.data==1){
  359. _this.posts.splice(index, 1);
  360. _data.localData('circle_data',_this.posts);
  361. _this.socket_push(_this.posts[index].id,'delete',_this.posts[index].userid,0);
  362. }else{
  363. uni.showModal({
  364. title:'网络连接失败'
  365. })
  366. }
  367. })
  368. }
  369. } });
  370. },
  371. comment_delete(index,index1){
  372. let _this = this
  373. var id=_this.posts[index].id;
  374. console.log(id);
  375. uni.showModal({
  376. title: '提示',
  377. content: '确定要删除吗?',
  378. showCancel: true,
  379. cancelText: '取消',
  380. confirmText: '删除',
  381. success: res => {
  382. if(res.confirm) {
  383. api.CommentDelete({id:id,index:index1}).then(res=>{
  384. if(res.data==1){
  385. this.socket_push(_this.posts[index].id,'delete',_this.posts[index].userid,0);
  386. _this.posts[index].comment.splice(index1, 1);
  387. _data.localData('circle_data',_this.posts);
  388. }else{
  389. uni.showModal({
  390. title:'网络连接失败'
  391. })
  392. }
  393. })
  394. }
  395. } });
  396. },
  397. like(index) {
  398. let _this = this,
  399. is_like = (_this.posts[index].islike ? 0 : 1);
  400. // console.log( _this.posts[index]);
  401. var data={id:_this.posts[index].id,userid:uni.getStorageSync('access_token')};
  402. api.setCircleLike(data).then(res=>{
  403. var data=res.data;
  404. _this.posts[index].islike=data.action;
  405. if (data.action) {
  406. _this.posts[index].like.push({
  407. "uid": _this.my_data.id,
  408. "username": _this.my_data.nickname,
  409. });
  410. } else {
  411. let likes = [];
  412. for(let i = 0,j = _this.posts[index].like.length;i < j; i ++){
  413. if(parseInt(_this.posts[index].like[i].uid) ==parseInt(uni.getStorageSync('access_token'))){
  414. _this.posts[index].like.splice(i, 1);
  415. break;
  416. }
  417. }
  418. }
  419. _data.localData('circle_data',_this.posts);
  420. this.socket_push(_this.posts[index].id,'like',_this.posts[index].userid,data.action);
  421. })
  422. },
  423. comment(index) {
  424. if(this.showInput){
  425. this.showInput = false;
  426. this.focus = false;
  427. this.index = '';
  428. }else{
  429. this.showInput = true; //调起input框
  430. this.focus = true;
  431. this.index = index;
  432. }
  433. },
  434. adjust() { //当弹出软键盘发生评论动作时,调整页面位置pageScrollTo
  435. },
  436. reply(index, comment_index) {
  437. this.is_reply = true; //回复中
  438. this.showInput = true; //调起input框
  439. let replyTo = this.posts[index].comment[comment_index].username;
  440. this.input_placeholder = '回复' + replyTo;
  441. this.index = index; //post索引
  442. this.comment_index = comment_index; //评论索引
  443. this.focus = true;
  444. },
  445. blur: function() {
  446. //this.init_input();
  447. },
  448. send_comment: function(message) {
  449. let _this = this,
  450. is_posts_obj = this.posts[this.index],
  451. chat_user_id = is_posts_obj.userid,
  452. reply = '';
  453. if(chat_user_id==undefined) chat_user_id=0
  454. if (this.is_reply) {
  455. let is_reply_obj = is_posts_obj.comment[this.comment_index];
  456. chat_user_id = is_reply_obj.uid;
  457. if(is_posts_obj.userid != chat_user_id){
  458. reply = '回复' + is_reply_obj.username;
  459. }
  460. }
  461. var data={
  462. message,
  463. id: is_posts_obj.id,
  464. chat_user_id,
  465. reply:reply,
  466. uid:uni.getStorageSync('access_token')
  467. }
  468. api.setCircleComment(data).then(res=>{
  469. is_posts_obj.comment.push({
  470. "uid": _this.my_data.id,
  471. 'reply': reply,
  472. "username": _this.my_data.nickname,
  473. "content": message
  474. });
  475. _this.init_input();
  476. _data.localData('circle_data',_this.posts);
  477. this.socket_push(_this.posts[this.index].id,'comment',_this.posts[this.index].userid,1);
  478. })
  479. },
  480. init_input() {
  481. this.showInput = false;
  482. this.focus = false;
  483. this.input_placeholder = '评论';
  484. this.is_reply = false;
  485. },
  486. previewImage(index, image_index) {
  487. let data = this.posts[index],
  488. images_all = [];
  489. for(let i = 0,j = data.content.value.length;i<j;i++){
  490. images_all.push(this.image_cache(data.content.value[i]));
  491. }
  492. var current = images_all[image_index];
  493. uni.previewImage({
  494. current: current,
  495. urls: images_all
  496. });
  497. },
  498. goPublish() {
  499. uni.navigateTo({
  500. url: './circle/send',
  501. success: res => {},
  502. fail: () => {},
  503. complete: () => {}
  504. });
  505. }
  506. },
  507. watch: {
  508. },
  509. }
  510. </script>
  511. <style scoped>
  512. @import url("../../static/css/circle.css");
  513. .new_msg {
  514. text-align: center;
  515. color: #333333;
  516. font-size: 32upx;
  517. }
  518. .inputbox{
  519. clear: both;
  520. width: 100%;
  521. display: flex;
  522. }
  523. .delete{
  524. display: inline-block;
  525. padding: 0px 20upx;
  526. color: #2319dc;
  527. font-size: 24upx;
  528. }
  529. </style>