index.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. <template>
  2. <page-meta page-style="overflow:hidden"></page-meta>
  3. <view class="page" :style="{height:winHeight +'px',overflow:'hidden'}">
  4. <!-- #ifdef APP-PLUS -->
  5. <view class="topTitle">
  6. <view class="topFont">
  7. 通讯录
  8. </view>
  9. <view class="titleLf">
  10. <image src="../../static/theme/default/chat/1.png" @click="goAdd" mode=""></image>
  11. </view>
  12. </view>
  13. <!-- #endif -->
  14. <!-- #ifdef H5 || MP-WEIXIN-->
  15. <view class="topTitle">
  16. <view class="topFont">
  17. 通讯录
  18. </view>
  19. <view class="titleLf">
  20. <image src="../../static/theme/default/chat/1.png" @click="goAdd" mode=""></image>
  21. </view>
  22. </view>
  23. <!-- #endif -->
  24. <scroll-view id="scrollcontent" class="scrollList" scroll-y :scroll-into-view="scrollViewId"
  25. :style="{paddingTop:status_height + jianrong +'px',height:winHeight+'px',boxSizing:'border-box'}">
  26. <view class="searchOut">
  27. <uni-search-bar ref="searchBar2" placeholder="搜索" :show="false" bgColor="#F7F7F7" @confirm="search"
  28. @search="search"></uni-search-bar>
  29. </view>
  30. <view class="listBox">
  31. <!-- <view class="header" v-if="0">
  32. <navigator :url="'phone-search'" hover-class="none" class="input-view">
  33. <uni-icon type="search" size="22" color="#666666"></uni-icon>
  34. <input class="input" type="text" placeholder="搜索我的朋友" :disabled="true" />
  35. </navigator>
  36. </view> -->
  37. <view class="listlf">
  38. <uni-list>
  39. <view class="uni-media-list btm_border" @click="goPath('../friend/apply-list',0)">
  40. <view class="uni-media-list-logo">
  41. <image src="../../static/theme/default/friend/im_contact_newfriend.png"
  42. class="img-icon" />
  43. </view>
  44. <view class="uni-media-list-body">
  45. <view class="uni-list-cell-navigate">新的朋友</view>
  46. </view>
  47. <view v-if="new_friend_tips > 0">
  48. <view class="red_num"><text>{{new_friend_tips}}</text></view>
  49. <view><text>&nbsp;</text></view>
  50. </view>
  51. </view>
  52. <view class="uni-media-list btm_border" @click="goPath('./group_chat')">
  53. <view class="uni-media-list-logo">
  54. <image src="../../static/theme/default/friend/im_contact_groupchat.png"
  55. class="img-icon" />
  56. </view>
  57. <view class="uni-media-list-body">
  58. <view class="uni-list-cell-navigate">群聊</view>
  59. </view>
  60. <view>
  61. <view class=""><text></text></view>
  62. <view><text>&nbsp;</text></view>
  63. </view>
  64. </view>
  65. <view class="uni-media-list" @tap="goPath('./chat-group-apply',1)">
  66. <view class="uni-media-list-logo">
  67. <image src="../../static/theme/default/friend/txl_icon_group_send.png"
  68. class="img-icon" />
  69. </view>
  70. <view class="uni-media-list-body">
  71. <view class="uni-list-cell-navigate">群认证</view>
  72. </view>
  73. <view v-if="new_group_tips > 0">
  74. <view class="red_num"><text>{{new_group_tips}}</text></view>
  75. <view><text>&nbsp;</text></view>
  76. </view>
  77. </view>
  78. <!-- <uni-list-item title="标签" :show-arrow="false"
  79. thumb="../../static/theme/default/friend/label.png" @click="goPath('')" v-if="0" />
  80. <uni-list-item title="小程序" :show-arrow="false"
  81. thumb="../../static/theme/default/friend/program.png" @click="goPath('')" v-if="0" /> -->
  82. </uni-list>
  83. <block v-for="(list, key) in list_data" :key="key">
  84. <view class="uni-list-cell-divider" :id="list.letter">
  85. {{list.letter}}
  86. </view>
  87. <view class="uni-list-cell" hover-class="none"
  88. :class="list.data.length -1 == index ? 'uni-list-cell-last' : ''"
  89. v-for="(item,index) in list.data" :key="isKey(key,index)">
  90. <uni-swipe-action :options="[ {text: '备注'} ]" @tap="swipeAction(item.user_id + '')">
  91. <view class="uni-media-list" @tap="goDetails(item.user_id + '')">
  92. <view class="uni-media-list-logo">
  93. <image :src="photo(item.photo+'')" :lazy-load="true"
  94. style="border-radius: 10px;" />
  95. </view>
  96. <view class="uni-media-list-body">
  97. <view class="uni-list-cell-navigate">{{item.name}}</view>
  98. </view>
  99. </view>
  100. </uni-swipe-action>
  101. </view>
  102. </block>
  103. </view>
  104. <view class="uni-indexed-list-bar" :class="touchmove ? 'active' : ''" @touchstart="touchStart"
  105. @touchmove.stop.prevent="touchMove" @touchend="touchEnd" @touchcancel="touchCancel"
  106. :style="{height:winHeight - tipHeight + 'px'}">
  107. <text v-for="(list,key) in key_data" :key="key" class="uni-indexed-list-text"
  108. :class="touchmoveIndex == key ? 'active' : ''"
  109. :style="{height:itemHeight + 'px',lineHeight:itemHeight + 'px'}">
  110. {{list}}
  111. </text>
  112. </view>
  113. </view>
  114. </scroll-view>
  115. <view class="uni-indexed-list-alert" v-if="touchmove">
  116. {{key_data[touchmoveIndex]}}
  117. </view>
  118. </view>
  119. </template>
  120. <script>
  121. import uniIcon from '../../components/uni-ui/uni-icon/uni-icon.vue';
  122. import uniList from '../../components/uni-ui/uni-list/uni-list.vue';
  123. import uniListItem from '../../components/uni-ui/uni-list-item/uni-list-item.vue';
  124. import uniSwipeAction from '../../components/uni-ui/uni-swipe-action/uni-swipe-action.vue'
  125. import _get from '../../common/_get';
  126. import _hook from '../../common/_hook';
  127. import _data from '../../common/_data';
  128. import _action from '../../common/_action';
  129. import uniSearchBar from '@/components/mehaotian-search/mehaotian-search.vue'
  130. export default {
  131. components: {
  132. uniIcon,
  133. uniList,
  134. uniListItem,
  135. uniSwipeAction,
  136. uniSearchBar,
  137. },
  138. data() {
  139. return {
  140. list_data: [],
  141. new_friend_tips: 0,
  142. new_group_tips: 0,
  143. title: 'grid',
  144. touchmove: false,
  145. touchmoveIndex: -1,
  146. itemHeight: 0,
  147. winHeight: 0,
  148. scrollViewId: "A",
  149. titleHeight: 120,
  150. search_list: [],
  151. keyword: '',
  152. key_data: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
  153. 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
  154. ],
  155. unread_msg: 0,
  156. status_height: 0,
  157. windowBottom: 0,
  158. tipHeight: 180, //jianxi
  159. jianrong: 0,
  160. }
  161. },
  162. onShow() {
  163. let sys = uni.getSystemInfoSync();
  164. this.winHeight = sys.windowHeight;
  165. this.status_height = sys.statusBarHeight;
  166. this.windowBottom = sys.windowBottom;
  167. this.itemHeight = (this.winHeight - this.tipHeight) / 26;
  168. // #ifdef H5
  169. this.jianrong = 56;
  170. // #endif
  171. // #ifdef APP-PLUS
  172. if (sys.platform == "android") {
  173. this.jianrong = 43;
  174. }
  175. if (sys.platform == "ios") {
  176. this.jianrong = 50;
  177. }
  178. // #endif
  179. _hook.routeTabBarHook();
  180. let _this = this,
  181. frien_list = _data.localData('frien_list'),
  182. tips_num = _data.data('new_friend_tips_num'),
  183. tips_group_apply = _data.data('new_group_tips_num');
  184. /** 监听最新数据 */
  185. uni.$on('data_friend_list', function(data) {
  186. _this.list_data = data;
  187. _this.search_list = data;
  188. });
  189. /** 监听新的朋友提示 */
  190. uni.$on('data_new_friend_tips', function(data) {
  191. _this.new_friend_tips = data;
  192. // console.log(_this.new_friend_tips);
  193. });
  194. /** 监听群认证消息 */
  195. uni.$on('data_new_group_apply_tips', function(data) {
  196. _this.new_group_tips = data;
  197. });
  198. _this.new_friend_tips = tips_num;
  199. _this.new_group_tips = tips_group_apply;
  200. /** 加载本地缓存数据,让页面秒速渲染出来 */
  201. if (frien_list) {
  202. _this.list_data = frien_list;
  203. } else {
  204. _get.getFriendList();
  205. }
  206. // 监听未读消息
  207. uni.$on('unread_concat_msg', (data) => {
  208. this.unread_msg = data;
  209. })
  210. },
  211. onLoad() {
  212. document.body.addEventListener('touchmove', function(e) {
  213. //阻止默认的处理方式(阻止下拉滑动的效果)
  214. e.preventDefault();
  215. }, {
  216. passive: false
  217. });
  218. },
  219. onHide() {
  220. uni.$off('data_friend_list');
  221. uni.$off('data_new_friend_tips');
  222. uni.$off('data_new_group_apply_tips');
  223. //清空search框
  224. if (this.keyword) {
  225. this.$refs.searchBar2.clear();
  226. this.list_data = this.search_list;
  227. }
  228. },
  229. computed: {
  230. staticPhoto() {
  231. return _data.staticPhoto();
  232. },
  233. },
  234. methods: {
  235. goAdd() {
  236. let _path = './add';
  237. uni.navigateTo({
  238. url: _path,
  239. });
  240. },
  241. search(keyword) {
  242. this.keyword = keyword.trim();
  243. let _this = this;
  244. if (!keyword) {
  245. // console.log(1111)
  246. // console.log(_this.search_list)
  247. _this.list_data = _this.search_list;
  248. return true;
  249. }
  250. _get.searchFriends({
  251. 'keyword': keyword
  252. }, function(data) {
  253. _this.list_data = data.data;
  254. })
  255. },
  256. photo(path) {
  257. return this.staticPhoto + path;
  258. },
  259. swipeAction(user_id) {
  260. uni.navigateTo({
  261. url: './remarks?user_id=' + user_id,
  262. animationType: 'slide-in-bottom',
  263. });
  264. },
  265. goDetails(user_id) {
  266. if (user_id) {
  267. uni.navigateTo({
  268. url: '../details/index?user_id=' + user_id,
  269. });
  270. }
  271. },
  272. goPath(path, type) {
  273. switch (type) {
  274. case 0:
  275. path += '?action=' + (this.new_friend_tips ? 1 : 0)
  276. this.new_friend_tips = 0;
  277. _data.data('new_friend_tips_num', 0);
  278. _action.setStatusTips();
  279. break;
  280. case 1:
  281. path += '?action=' + (this.new_group_tips ? 1 : 0);
  282. this.new_group_tips = 0;
  283. _data.data('new_group_tips_num', 0);
  284. _action.setStatusTips();
  285. break;
  286. default:
  287. break;
  288. }
  289. if (path) {
  290. uni.navigateTo({
  291. url: path,
  292. });
  293. }
  294. },
  295. isKey(key, index) {
  296. return key + '' + index;
  297. },
  298. touchStart(e) {
  299. this.touchmove = true;
  300. let pageY = e.touches[0].pageY;
  301. console.log("pageY", pageY);
  302. let index = Math.floor((pageY - this.titleHeight) / this.itemHeight);
  303. // #ifdef APP-PLUS
  304. index = Math.floor((pageY - this.titleHeight - this.status_height) / this.itemHeight);
  305. // #endif
  306. // console.log("index", index)
  307. let item = this.list_data[index];
  308. // console.log("list_data", this.list_data)
  309. // console.log("item", item)
  310. if (item) {
  311. this.scrollViewId = item.letter;
  312. }
  313. this.touchmoveIndex = index;
  314. },
  315. touchMove(e) {
  316. let pageY = e.touches[0].pageY;
  317. let index = Math.floor((pageY - this.titleHeight) / this.itemHeight);
  318. // #ifdef APP-PLUS
  319. index = Math.floor((pageY - this.titleHeight - this.status_height) / this.itemHeight);
  320. // #endif
  321. let item = this.list_data[index];
  322. if (item) {
  323. this.scrollViewId = item.letter;
  324. this.touchmoveIndex = index;
  325. }
  326. },
  327. touchEnd() {
  328. this.touchmove = false;
  329. //this.touchmoveIndex = -1;
  330. },
  331. touchCancel() {
  332. this.touchmove = false;
  333. //this.touchmoveIndex = -1;
  334. },
  335. },
  336. watch: {
  337. },
  338. onNavigationBarButtonTap(e) {
  339. let _path = e.index ? './phone-search' : './add';
  340. uni.navigateTo({
  341. url: _path,
  342. });
  343. }
  344. }
  345. </script>
  346. <style>
  347. page {
  348. background: #fff;
  349. height: 100%;
  350. }
  351. .page {
  352. /* display: flex;
  353. flex-direction: row; */
  354. height: 100%;
  355. background-color: #fff;
  356. }
  357. .scrollList {
  358. overflow-y: auto;
  359. overflow-x: hidden;
  360. -webkit-overflow-scrolling: touch;
  361. }
  362. .uni-indexed-list-bar {
  363. width: 40upx;
  364. background-color: transparent;
  365. display: flex;
  366. flex-direction: column;
  367. padding-right: 10rpx;
  368. position: fixed;
  369. right: 0;
  370. top: 240rpx;
  371. z-index: 10;
  372. }
  373. .uni-indexed-list-bar.active {
  374. /* background-color: rgb(200, 200, 200); */
  375. }
  376. .uni-indexed-list-text {
  377. font-size: 22upx;
  378. text-align: center;
  379. }
  380. .uni-indexed-list-bar.active .uni-indexed-list-text {
  381. color: #333;
  382. }
  383. .uni-indexed-list-text.active,
  384. .uni-indexed-list-bar.active .uni-indexed-list-text.active {
  385. color: #02b300;
  386. }
  387. .uni-indexed-list-alert {
  388. position: absolute;
  389. z-index: 20;
  390. width: 160upx;
  391. height: 160upx;
  392. left: 50%;
  393. top: 50%;
  394. margin-left: -80upx;
  395. margin-top: -80upx;
  396. border-radius: 80upx;
  397. text-align: center;
  398. line-height: 160upx;
  399. font-size: 70upx;
  400. color: #fff;
  401. background-color: rgba(0, 0, 0, 0.5);
  402. }
  403. .header {
  404. display: flex;
  405. flex-direction: row;
  406. padding: 10px 15px;
  407. align-items: center;
  408. }
  409. .input-view {
  410. display: flex;
  411. align-items: center;
  412. flex-direction: row;
  413. background-color: #e7e7e7;
  414. height: 30px;
  415. border-radius: 5px;
  416. padding: 0 10px;
  417. flex: 1;
  418. }
  419. .input {
  420. flex: 1;
  421. padding: 0 5px;
  422. height: 24px;
  423. line-height: 24px;
  424. font-size: 16px;
  425. }
  426. .uni-list-cell-navigate {
  427. padding: 0;
  428. }
  429. .uni-media-list-body {
  430. height: auto;
  431. }
  432. .uni-media-list image {
  433. border-radius: 10px;
  434. }
  435. .uni-swipe-action {
  436. width: 710upx !important;
  437. }
  438. .btm_border {
  439. position: relative;
  440. display: flex;
  441. flex-direction: row;
  442. justify-content: space-between;
  443. align-items: center;
  444. }
  445. /* .btm_border::after {
  446. position: absolute;
  447. z-index: 3;
  448. right: 0;
  449. bottom: 0;
  450. left: 115upx;
  451. height: 1px;
  452. content: "";
  453. -webkit-transform: scaleY(0.5);
  454. transform: scaleY(0.5);
  455. background-color: #e7e6ef;
  456. } */
  457. .img-icon {
  458. width: 85upx;
  459. height: 85upx;
  460. border-radius: 10upx;
  461. }
  462. .uni-media-list-logo {
  463. height: 85upx;
  464. width: 85upx;
  465. /* margin-right: 20upx; */
  466. }
  467. .red_num {
  468. background-color: #f43530;
  469. width: 35upx;
  470. border-radius: 18upx;
  471. text-align: center;
  472. height: 35upx;
  473. line-height: 35upx;
  474. color: #ffffff;
  475. font-size: 23upx !important;
  476. }
  477. .topTitle {
  478. background-color: #fff;
  479. box-sizing: border-box;
  480. padding: 20rpx 30rpx;
  481. /* #ifdef APP-PLUS */
  482. padding-top: var(--status-bar-height);
  483. /* #endif */
  484. display: flex;
  485. justify-content: space-between;
  486. align-items: center;
  487. width: 100vw;
  488. position: fixed;
  489. top: 0;
  490. left: 0;
  491. background: #fff;
  492. z-index: 10;
  493. }
  494. .topFont {
  495. font-size: 40rpx;
  496. color: #080E18;
  497. font-weight: bold;
  498. margin-left: 10rpx;
  499. }
  500. .titleLf {
  501. display: flex;
  502. justify-content: flex-end;
  503. align-items: center;
  504. }
  505. .titleLf>image {
  506. width: 40rpx;
  507. height: 40rpx;
  508. }
  509. .listBox {
  510. display: flex;
  511. justify-content: space-between;
  512. align-content: flex-start;
  513. flex-wrap: nowrap;
  514. flex-direction: row;
  515. padding-right: 10rpx;
  516. padding-left: 14rpx;
  517. /* #ifdef APP-PLUS */
  518. padding-bottom: 160rpx;
  519. /* #endif */
  520. }
  521. .listlf {
  522. /* flex: 1; */
  523. }
  524. .searchOut {
  525. box-sizing: border-box;
  526. padding: 0 28rpx;
  527. }
  528. .searchOut .search {
  529. padding: 14rpx 0 !important;
  530. }
  531. </style>
  532. <style>
  533. .icon-search {
  534. padding: 0 4rpx !important;
  535. }
  536. .search .content {
  537. padding-left: 20upx;
  538. height: 60upx;
  539. background-color: #F7F7F7 !important;
  540. }
  541. .uni-list .uni-media-list {
  542. padding-left: 0;
  543. }
  544. </style>