circle.vue 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. <template>
  2. <view id="moments" class="page">
  3. <view class="home-pic">
  4. <image :src="photo(my_data.circle_img)" @tap="uploadBefore" 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)"
  8. :lazy-load="true" />
  9. </view>
  10. <view class="top-name">{{ my_data.nickname }}</view>
  11. </view>
  12. </view>
  13. <view class="new_msg" style="color: #333333;" @tap="goCircleChat" v-if="no_reader_msg">你有<view
  14. style="color: #ff0000;display: inline;">{{no_reader_msg}}条</view>新的消息</view>
  15. <view class="moments__post1" v-for="(post,index) in posts" :key="index" :id="'post-'+index">
  16. <view class="moments__post">
  17. <view class="post-left">
  18. <image class="post_header" :src="image_cache(post.header_image)" @tap="goDetails(post.userid)"
  19. :lazy-load="true" />
  20. </view>
  21. <view class="post_right">
  22. <view class="post-username" @tap="goDetails(post.uid)">{{post.username}}</view>
  23. <view id="paragraph" class="paragraph" @tap="init_input()">{{post.content.text}}</view>
  24. <!-- 相册 -->
  25. <view class="thumbnails" v-if="post.type == 0" @tap="init_input()">
  26. <view :class="post.content.value.length === 1 ? 'my-gallery' : 'thumbnail' "
  27. v-for="(image, index_images) in post.content.value" :key="index_images">
  28. <image class="gallery_img" :lazy-load="true" mode="aspectFill"
  29. :src="image_cache(staticPath + image)" :data-src="image"
  30. @tap="previewImage(index,index_images)" />
  31. </view>
  32. </view>
  33. <!-- 资料条 -->
  34. <view class="toolbar">
  35. <view class="timestamp">{{ post.timestamp }}
  36. <view class="delete" v-if="post.userid==myid" @tap="circle_delete(index)">删除</view>
  37. </view>
  38. <view class="like" @tap="like(index)">
  39. <image
  40. :src="post.islike === 0 ? '../../static/push/circle/islike.png' : '../../static/push/circle/like.png'"
  41. :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" v-for="(user,index_like) in post.like" :key="index_like"
  52. @tap="goDetails(user.uid)">
  53. {{(index_like ? ',' : '' ) + user.username}}
  54. </view>
  55. </view>
  56. <view class="footer_content" v-for="(comment,comment_index) in post.comment"
  57. :key="comment_index" @tap="reply(index,comment_index)">
  58. <view class="comment-nickname" style="word-break:break-all;line-height: 40upx;">
  59. {{comment.username + comment.reply + ': '}}
  60. <text class="comment-content">
  61. {{comment.content}}
  62. </text>
  63. <view class="delete" style="float: right;" v-if="comment.uid==myid"
  64. @tap="comment_delete(index,comment_index)">删除</view>
  65. </view>
  66. </view>
  67. </view>
  68. </view>
  69. </view>
  70. <!-- 结束 post -->
  71. </view>
  72. <view class="foot" style="z-index: 999999;" v-show="showInput">
  73. <chat-input @send-message="send_comment" @blur="blur" :focus="focus"
  74. :placeholder="input_placeholder"></chat-input>
  75. <!-- <chat-input @send-message="send_comment" @blur="blur" :placeholder="input_placeholder"></chat-input> -->
  76. </view>
  77. <view class="loadmore" v-if="showLoadMore">{{loadMoreText}}</view>
  78. <yk-authpup ref="WRITE_EXTERNAL_STORAGE" type="top" @changeAuth="changeAuth"
  79. permissionID="WRITE_EXTERNAL_STORAGE"></yk-authpup>
  80. </view>
  81. </template>
  82. <script>
  83. import ykAuthpup from "@/components/yk-authpup/yk-authpup";
  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. ykAuthpup
  97. },
  98. data() {
  99. return {
  100. my_data: {},
  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() {
  163. _this.setCircleData(circle_data);
  164. }, 10);
  165. _this.pullDownRefresh();
  166. } else {
  167. _this.setCircleData([]);
  168. _this.pullDownRefresh();
  169. }
  170. console.log('+++');
  171. },
  172. onUnload() {
  173. this.$socket.off('data_circle_tips');
  174. this.$socket.off('circle_push');
  175. uni.offWindowResize(); //取消监听窗口尺寸变化
  176. this.max = 0,
  177. this.data = [],
  178. this.loadMoreText = "加载更多",
  179. this.showLoadMore = false;
  180. },
  181. onReachBottom() { //监听上拉触底事件
  182. let _this = this;
  183. _this.showLoadMore = true;
  184. if (_this.is_more) {
  185. return;
  186. }
  187. this.page++;
  188. this.onGetData();
  189. },
  190. onPullDownRefresh() { //监听下拉刷新动作
  191. if (_data.data('no_reader_circle') || _data.data('no_reader_circle_chat_num')) {
  192. this.posts = [];
  193. _data.data('circle_data', []);
  194. }
  195. this.pullDownRefresh();
  196. },
  197. onNavigationBarButtonTap(e) { //监听标题栏点击事件
  198. if (e.index == 0) {
  199. this.navigateTo('./circle/send');
  200. }
  201. },
  202. methods: {
  203. photo(path) {
  204. if (path.indexOf('http') <= -1) return path;
  205. else return this.image_cache(path)
  206. },
  207. onshowlisten() {
  208. this.no_reader_msg = uni.getStorageSync('data_circle_tips') ? uni.getStorageSync('data_circle_tips') :
  209. 0;
  210. action.setStatusTips();
  211. _data.data('no_reader_circle', 0);
  212. // 监听窗口尺寸变化,窗口尺寸不包括底部导航栏
  213. uni.onWindowResize((res) => {
  214. if (this.platform === 'ios') {
  215. this.windowHeight = res.size.windowHeight;
  216. this.adjust();
  217. } else {
  218. if (this.screenHeight - res.size.windowHeight > 60 && this.windowHeight <= res.size
  219. .windowHeight) {
  220. this.windowHeight = res.size.windowHeight;
  221. this.adjust();
  222. }
  223. }
  224. });
  225. this.$socket.on('circle_push', (res) => { //更新朋友圈消息
  226. action.circleUpate(res.data);
  227. this.posts = _data.cache('circle_data');
  228. })
  229. /** 监听朋友圈动态提示 */
  230. this.$socket.on('data_circle_tips', function(res) {
  231. if (!isNaN(res.data)) {
  232. _this.no_reader_msg = res.data;
  233. };
  234. uni.setStorageSync('data_circle_tips', res.data);
  235. action.setStatusTips();
  236. });
  237. },
  238. uploadBefore() {
  239. // #ifdef APP-PLUS
  240. if (plus.os.name == 'Android') {
  241. return this.$refs['WRITE_EXTERNAL_STORAGE'].open()
  242. } else {
  243. this.upload()
  244. }
  245. // #endif
  246. // #ifdef H5
  247. this.upload()
  248. // #endif
  249. },
  250. changeAuth() {
  251. this.upload()
  252. },
  253. upload(e) {
  254. uni.chooseImage({
  255. sourceType: ['album'],
  256. success: (chooseImageRes) => {
  257. uni.showLoading();
  258. const tempFilePaths = chooseImageRes.tempFilePaths;
  259. helper.uploadFiles(tempFilePaths, 'image', {
  260. type: 'avatar'
  261. }).then(res => {
  262. this.my_data.circle_img = res;
  263. // console.log(res);
  264. var avatar = res.replace(config.imgUri, '');
  265. api.changeProfile({
  266. circle_img: avatar,
  267. id: this.my_data.id
  268. }).then(res => {
  269. uni.hideLoading()
  270. this.$toast('更新成功').then(() => {
  271. });
  272. });
  273. })
  274. }
  275. });
  276. },
  277. onGetData() {
  278. let time = 0;
  279. let circle_data11 = _data.localData('circle_data');
  280. if (circle_data11.length > 0) {
  281. time = circle_data11[0].time;
  282. }
  283. let that = this;
  284. // _data.localData('circle_data',[])
  285. api.getCircleList({
  286. userid: uni.getStorageSync('access_token'),
  287. page: this.page
  288. }).then(res => {
  289. if (this.page == 1) _data.addData('circle_data', res.data)
  290. // console.log(circle_data);
  291. that.setCircleData(res.data);
  292. // uni.$emit('data_circle_data',circle_data);
  293. if (res.data.length < 10) {
  294. this.loadMoreText = '没有更多数据了';
  295. this.is_more = true;
  296. this.showLoadMore = true;
  297. }
  298. })
  299. },
  300. setCircleData(data) {
  301. var list11 = [];
  302. var len = data.length;
  303. let circle_data11 = _data.localData('circle_data');
  304. if (circle_data11.length > 0 && this.page > 1) {
  305. var time = circle_data11[circle_data11.length - 1].time;
  306. }
  307. // if(len>20) len=20;
  308. for (var i = 0; i < len; i++) {
  309. var item = data[i];
  310. if (item.like == false) item.like = [];
  311. if (item.comment == false) item.comment = [];
  312. item.timestamp = action.timestampFormat(item.time);
  313. item.islike = this.setisLike(uni.getStorageSync('access_token'), item.like);
  314. if (item.time < time || this.page == 1) list11.push(item);
  315. }
  316. if (this.page == 1) {
  317. this.posts = list11;
  318. } else this.posts.push(...list11);
  319. },
  320. setisLike(id, data) {
  321. if (data.length == 0 || data == []) return 0;
  322. for (var i = 0; i < data.length; i++) {
  323. if (data[i].uid == id) return 1;
  324. }
  325. return 0;
  326. },
  327. goCircleChat() {
  328. _data.data('no_reader_circle_chat_num', 0);
  329. this.navigateTo('./circle_chat_details');
  330. },
  331. getUserInfo() {
  332. let _this = this;
  333. api.getUserInfo({
  334. friend_uid: uni.getStorageSync('access_token')
  335. }).then(res => {
  336. _this.my_data.id = res.data.id;
  337. _this.my_data.nickname = res.data.nickname;
  338. var photo = res.data.avatar;
  339. if (photo.indexOf('http') <= -1) photo = config.imgUri + photo;
  340. _this.my_data.photo = photo;
  341. if (res.data.circle_img != null) {
  342. this.my_data.circle_img = this.image_cache(res.data.circle_img);
  343. }
  344. })
  345. },
  346. pullDownRefresh() {
  347. var _this = this;
  348. //初始化数据
  349. // this.onGetData();
  350. setTimeout(function() {
  351. _this.onGetData();
  352. }, 100);
  353. uni.stopPullDownRefresh(); //停止下拉刷新
  354. /** 取消好友动态提示 */
  355. _data.data('no_reader_circle', 0);
  356. },
  357. goDetails(user_id) {
  358. this.navigateTo('../friend/detail?id=' + user_id);
  359. },
  360. navigateTo(url) {
  361. uni.navigateTo({
  362. url: url
  363. });
  364. },
  365. socket_push(id, action, userid, issend) {
  366. let data = {
  367. type: 'circle_push',
  368. id: id,
  369. action: action,
  370. fromid: uni.getStorageSync('access_token'),
  371. userid: userid,
  372. issend: issend
  373. }
  374. this.$socket.send(data);
  375. },
  376. circle_delete(index) {
  377. let _this = this
  378. uni.showModal({
  379. title: '提示',
  380. content: '确定要删除吗?',
  381. showCancel: true,
  382. cancelText: '取消',
  383. confirmText: '删除',
  384. success: res => {
  385. if (res.confirm) {
  386. var id = _this.posts[index].id;
  387. api.CircleDelete({
  388. id: id
  389. }).then(res => {
  390. if (res.data == 1) {
  391. _this.posts.splice(index, 1);
  392. _data.localData('circle_data', _this.posts);
  393. _this.socket_push(_this.posts[index].id, 'delete', _this.posts[
  394. index].userid, 0);
  395. } else {
  396. uni.showModal({
  397. title: '网络连接失败'
  398. })
  399. }
  400. })
  401. }
  402. }
  403. });
  404. },
  405. comment_delete(index, index1) {
  406. let _this = this
  407. var id = _this.posts[index].id;
  408. console.log(id);
  409. uni.showModal({
  410. title: '提示',
  411. content: '确定要删除吗?',
  412. showCancel: true,
  413. cancelText: '取消',
  414. confirmText: '删除',
  415. success: res => {
  416. if (res.confirm) {
  417. api.CommentDelete({
  418. id: id,
  419. index: index1
  420. }).then(res => {
  421. if (res.data == 1) {
  422. this.socket_push(_this.posts[index].id, 'delete', _this.posts[
  423. index].userid, 0);
  424. _this.posts[index].comment.splice(index1, 1);
  425. _data.localData('circle_data', _this.posts);
  426. } else {
  427. uni.showModal({
  428. title: '网络连接失败'
  429. })
  430. }
  431. })
  432. }
  433. }
  434. });
  435. },
  436. like(index) {
  437. let _this = this,
  438. is_like = (_this.posts[index].islike ? 0 : 1);
  439. // console.log( _this.posts[index]);
  440. var data = {
  441. id: _this.posts[index].id,
  442. userid: uni.getStorageSync('access_token')
  443. };
  444. api.setCircleLike(data).then(res => {
  445. var data = res.data;
  446. _this.posts[index].islike = data.action;
  447. if (data.action) {
  448. _this.posts[index].like.push({
  449. "uid": _this.my_data.id,
  450. "username": _this.my_data.nickname,
  451. });
  452. } else {
  453. let likes = [];
  454. for (let i = 0, j = _this.posts[index].like.length; i < j; i++) {
  455. if (parseInt(_this.posts[index].like[i].uid) == parseInt(uni.getStorageSync(
  456. 'access_token'))) {
  457. _this.posts[index].like.splice(i, 1);
  458. break;
  459. }
  460. }
  461. }
  462. _data.localData('circle_data', _this.posts);
  463. this.socket_push(_this.posts[index].id, 'like', _this.posts[index].userid, data.action);
  464. })
  465. },
  466. comment(index) {
  467. if (this.showInput) {
  468. this.showInput = false;
  469. this.focus = false;
  470. this.index = '';
  471. } else {
  472. this.showInput = true; //调起input框
  473. this.focus = true;
  474. this.index = index;
  475. }
  476. },
  477. adjust() { //当弹出软键盘发生评论动作时,调整页面位置pageScrollTo
  478. },
  479. reply(index, comment_index) {
  480. this.is_reply = true; //回复中
  481. this.showInput = true; //调起input框
  482. let replyTo = this.posts[index].comment[comment_index].username;
  483. this.input_placeholder = '回复' + replyTo;
  484. this.index = index; //post索引
  485. this.comment_index = comment_index; //评论索引
  486. this.focus = true;
  487. },
  488. blur: function() {
  489. //this.init_input();
  490. },
  491. send_comment: function(message) {
  492. let _this = this,
  493. is_posts_obj = this.posts[this.index],
  494. chat_user_id = is_posts_obj.userid,
  495. reply = '';
  496. if (chat_user_id == undefined) chat_user_id = 0
  497. if (this.is_reply) {
  498. let is_reply_obj = is_posts_obj.comment[this.comment_index];
  499. chat_user_id = is_reply_obj.uid;
  500. if (is_posts_obj.userid != chat_user_id) {
  501. reply = '回复' + is_reply_obj.username;
  502. }
  503. }
  504. var data = {
  505. message,
  506. id: is_posts_obj.id,
  507. chat_user_id,
  508. reply: reply,
  509. uid: uni.getStorageSync('access_token')
  510. }
  511. api.setCircleComment(data).then(res => {
  512. is_posts_obj.comment.push({
  513. "uid": _this.my_data.id,
  514. 'reply': reply,
  515. "username": _this.my_data.nickname,
  516. "content": message
  517. });
  518. _this.init_input();
  519. _data.localData('circle_data', _this.posts);
  520. this.socket_push(_this.posts[this.index].id, 'comment', _this.posts[this.index].userid,
  521. 1);
  522. })
  523. },
  524. init_input() {
  525. this.showInput = false;
  526. this.focus = false;
  527. this.input_placeholder = '评论';
  528. this.is_reply = false;
  529. },
  530. previewImage(index, image_index) {
  531. let data = this.posts[index],
  532. images_all = [];
  533. for (let i = 0, j = data.content.value.length; i < j; i++) {
  534. images_all.push(this.image_cache(data.content.value[i]));
  535. }
  536. var current = images_all[image_index];
  537. uni.previewImage({
  538. current: current,
  539. urls: images_all
  540. });
  541. },
  542. goPublish() {
  543. uni.navigateTo({
  544. url: './circle/send',
  545. success: res => {},
  546. fail: () => {},
  547. complete: () => {}
  548. });
  549. }
  550. },
  551. watch: {
  552. },
  553. }
  554. </script>
  555. <style scoped>
  556. @import url("../../static/css/circle.css");
  557. .new_msg {
  558. text-align: center;
  559. color: #333333;
  560. font-size: 32upx;
  561. }
  562. .inputbox {
  563. clear: both;
  564. width: 100%;
  565. display: flex;
  566. }
  567. .delete {
  568. display: inline-block;
  569. padding: 0px 20upx;
  570. color: #2319dc;
  571. font-size: 24upx;
  572. }
  573. </style>