addressbook.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <template>
  2. <view>
  3. <cu-custom bgColor="bg-blue">
  4. <block slot="content">通讯录</block>
  5. </cu-custom>
  6. <view class="cu-bar bg-white search fixed" :style="[{top:CustomBar + 'px'}]">
  7. <view class="search-form round">
  8. <text class="cuIcon-search"></text>
  9. <input type="text" v-model="searchUserName" placeholder="输入搜索的关键词" confirm-type="search"></input>
  10. </view>
  11. <view class="action">
  12. <button class="cu-btn bg-blue shadow-blur round">搜索</button>
  13. </view>
  14. </view>
  15. <scroll-view scroll-y class="indexes x-page" :scroll-into-view="'indexes-'+ listCurID" :style="[{height:'calc(100vh - '+ CustomBar + 'px - 50px)'}]"
  16. :scroll-with-animation="true" :enable-back-to-top="true">
  17. <block v-for="(item,index) in list" :key="index">
  18. <view :class="'indexItem-' + item.letter" :id="'indexes-' + item.letter" :data-index="item.letter">
  19. <view class="padding">{{item.letter}}</view>
  20. <view class="cu-list menu-avatar no-padding">
  21. <view class="cu-item" v-for="(user,sub) in item.data" :key="sub">
  22. <!-- <view class="cu-avatar round lg">{{user.name}}</view> -->
  23. <view class="cu-avatar lg round " :style="'background-image:url('+(user.photo?user.photo:'/static/user/flat-avatar.png')+');'"></view>
  24. <view class="content">
  25. <view class="text-grey"><text class="text-abc">{{user.name}}</text></view>
  26. <view class="text-gray text-sm">
  27. {{user.companyDTO && user.companyDTO.name}} {{user.officeDTO && user.officeDTO.name}}
  28. </view>
  29. </view>
  30. </view>
  31. </view>
  32. </view>
  33. </block>
  34. </scroll-view>
  35. <view class="indexBar" :style="[{height:'calc(100vh - ' + CustomBar + 'px - 50px)'}]">
  36. <view class="indexBar-box" @touchstart="tStart" @touchend="tEnd" @touchmove.stop="tMove">
  37. <view class="indexBar-item" v-for="(item,index) in list" :key="index" :id="index" @touchstart="getCur" @touchend="setCur"> {{item.letter}}</view>
  38. </view>
  39. </view>
  40. <!--选择显示-->
  41. <view v-show="!hidden" class="indexToast">
  42. {{listCur}}
  43. </view>
  44. <view class="cu-tabbar-height"></view>
  45. </view>
  46. </template>
  47. <script>
  48. import userService from '@/api/sys/userService'
  49. export default {
  50. data() {
  51. return {
  52. StatusBar: this.StatusBar,
  53. CustomBar: this.CustomBar,
  54. searchUserName: '',
  55. hidden: true,
  56. listCurID: '',
  57. userList: [],
  58. listCur: '',
  59. };
  60. },
  61. created() {
  62. userService.list({current: 1, size: -1}).then(({data})=>{
  63. this.userList = data.records
  64. }).catch((e)=>{
  65. throw e
  66. })
  67. },
  68. mounted() {
  69. let that = this;
  70. uni.createSelectorQuery().select('.indexBar-box').boundingClientRect(function(res) {
  71. that.boxTop = res.top
  72. }).exec();
  73. },
  74. computed: {
  75. list () {
  76. let resultList = this.userList.filter((item)=>{
  77. if(item.name.indexOf(this.searchUserName) >= 0){
  78. return true
  79. }
  80. })
  81. return this.pySegSort(resultList)
  82. }
  83. },
  84. methods: {
  85. //获取文字信息
  86. getCur(e) {
  87. this.hidden = false;
  88. this.listCur = this.list[e.target.id].letter;
  89. },
  90. // 排序
  91. pySegSort(arr) {
  92. if(!String.prototype.localeCompare)
  93. return null;
  94. var letters = "0abcdefghjklmnopqrstwxyz".split('');
  95. var zh = "阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀".split('');
  96. var segs = [];
  97. var curr;
  98. letters.forEach(function(item,i){
  99. curr = {letter: item, data:[]};
  100. arr.forEach(function(item2){
  101. if((!zh[i-1] || zh[i-1].localeCompare(item2.name) <= 0) && item2.name.localeCompare(zh[i]) == -1) {
  102. curr.data.push(item2);
  103. }
  104. });
  105. if(curr.data.length) {
  106. segs.push(curr);
  107. curr.data.sort(function(a,b){
  108. return a.name.localeCompare(b.name);
  109. });
  110. }
  111. });
  112. return segs;
  113. },
  114. setCur(e) {
  115. this.hidden = true;
  116. this.listCur = this.listCur
  117. },
  118. //滑动选择Item
  119. tMove(e) {
  120. let y = e.touches[0].clientY,
  121. offsettop = this.boxTop,
  122. that = this;
  123. //判断选择区域,只有在选择区才会生效
  124. if (y > offsettop) {
  125. let num = parseInt((y - offsettop) / 20);
  126. this.listCur = that.list[num].letter
  127. };
  128. },
  129. //触发全部开始选择
  130. tStart() {
  131. this.hidden = false
  132. },
  133. //触发结束选择
  134. tEnd() {
  135. this.hidden = true;
  136. this.listCurID = this.listCur
  137. },
  138. indexSelect(e) {
  139. let that = this;
  140. let barHeight = this.barHeight;
  141. let list = this.list;
  142. let scrollY = Math.ceil(list.length * e.detail.y / barHeight);
  143. for (let i = 0; i < list.length; i++) {
  144. if (scrollY < i + 1) {
  145. that.listCur = list[i].letter;
  146. that.movableY = i * 20
  147. return false
  148. }
  149. }
  150. }
  151. }
  152. }
  153. </script>
  154. <style>
  155. .x-page {
  156. padding-top: 100upx;
  157. }
  158. .indexes {
  159. position: relative;
  160. }
  161. .indexBar {
  162. position: fixed;
  163. right: 0px;
  164. bottom: 0px;
  165. padding: 20upx 20upx 20upx 60upx;
  166. display: flex;
  167. align-items: center;
  168. }
  169. .indexBar .indexBar-box {
  170. width: 40upx;
  171. height: auto;
  172. background: #fff;
  173. display: flex;
  174. flex-direction: column;
  175. box-shadow: 0 0 20upx rgba(0, 0, 0, 0.1);
  176. border-radius: 10upx;
  177. }
  178. .indexBar-item {
  179. flex: 1;
  180. width: 40upx;
  181. height: 40upx;
  182. display: flex;
  183. align-items: center;
  184. justify-content: center;
  185. font-size: 24upx;
  186. color: #888;
  187. }
  188. movable-view.indexBar-item {
  189. width: 40upx;
  190. height: 40upx;
  191. z-index: 9;
  192. position: relative;
  193. }
  194. movable-view.indexBar-item::before {
  195. content: "";
  196. display: block;
  197. position: absolute;
  198. left: 0;
  199. top: 10upx;
  200. height: 20upx;
  201. width: 4upx;
  202. background-color: #f37b1d;
  203. }
  204. .indexToast {
  205. position: fixed;
  206. top: 0;
  207. right: 80upx;
  208. bottom: 0;
  209. background: rgba(0, 0, 0, 0.5);
  210. width: 100upx;
  211. height: 100upx;
  212. border-radius: 10upx;
  213. margin: auto;
  214. color: #fff;
  215. line-height: 100upx;
  216. text-align: center;
  217. font-size: 48upx;
  218. }
  219. </style>