uniapp,h5

tabbar-4.vue 7.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <template>
  2. <view class="container">
  3. <view class="search-container">
  4. <uni-search-bar class="uni-mt-10" radius="5" placeholder="输入用户名搜索用户" clearButton="auto" cancelButton="none"
  5. @confirm="search" :focus="true" v-model="searchValue" @blur="blur" @focus="focus" @input="onInput"
  6. @clear="clear">
  7. </uni-search-bar>
  8. <!-- 显示搜索结果 -->
  9. <view v-if="searchValue" class="search-result">
  10. <text class="result-title">搜索结果</text>
  11. <view class="result-item" v-for="(item, index) in searchResults" :key="index"
  12. @click="goToChat(item.userId)">
  13. <image class="avatar" :src="item.avatar_url"></image>
  14. <view class="text-container">
  15. <text class="username">{{ item.username }}</text>
  16. <text class="bio">{{ item.bio }}</text>
  17. </view>
  18. </view>
  19. </view>
  20. </view>
  21. <uni-list>
  22. <uni-list :border="true">
  23. <!-- 单人右侧带角标 -->
  24. <uni-list-chat title="所有人聊天" avatar="https://afanai.top:8088/imgs/default_avatar_all.png"
  25. note="您有一条新消息..." time="2020-02-02 20:20" badge-text="1" :clickable="true" @click="goToChat('000')">
  26. </uni-list-chat>
  27. <!-- 多人显示多头像 -->
  28. <!-- <uni-list-chat title="周雨萌" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20"
  29. badge-text="99" :clickable="true" @click="goToChat()"> </uni-list-chat> -->
  30. <!-- 循环渲染每一个聊天对话 -->
  31. <uni-list-chat v-for="(item, index) in chatItems" :key="index" :title="item.name"
  32. :avatar="item.avatarList" :note="item.note" :time="item.time" :badge-text="item.unreadCount"
  33. :clickable="true" @click="goToChat(item.id)">
  34. </uni-list-chat>
  35. </uni-list>
  36. </uni-list>
  37. </view>
  38. </template>
  39. <script>
  40. export default {
  41. data() {
  42. return {
  43. chatItems: [],
  44. user: {
  45. avatar: '',
  46. email: '',
  47. username: '',
  48. bio: '',
  49. userId: ''
  50. },
  51. searchValue: '',
  52. debounceTimer: null,
  53. searchResults: []
  54. }
  55. },
  56. onLoad() {
  57. let userInfo = uni.getStorageSync('userInfo');
  58. if (userInfo) {
  59. this.user = {
  60. ...userInfo
  61. };
  62. }
  63. },
  64. onShow: async function() {
  65. this.searchValue = '';
  66. try {
  67. await this.fetchMsgList();
  68. } catch (error) {
  69. console.error('Failed to load msg list:', error);
  70. }
  71. },
  72. methods: {
  73. async search(res) {
  74. this.searchResults = await this.fetchSearchResults(this.searchValue);
  75. },
  76. focus(e) {
  77. uni.showToast({
  78. title: 'focus事件,输出值为:' + e.value,
  79. icon: 'none'
  80. })
  81. },
  82. async onInput(e) {
  83. // console.log(e);
  84. this.searchValue = e.value;
  85. // console.log(this.searchValue);
  86. // 清除上一个计时器,防止重复调用
  87. if (this.debounceTimer) {
  88. clearTimeout(this.debounceTimer);
  89. }
  90. // 设置新的计时器,在用户停止输入300ms后调用fetchSearchResults
  91. this.debounceTimer = setTimeout(async () => {
  92. if (this.searchValue) {
  93. this.searchResults = await this.fetchSearchResults(this.searchValue);
  94. } else {
  95. this.searchResults = [];
  96. }
  97. }, 200);
  98. },
  99. async fetchSearchResults(query) {
  100. // 调用后端接口
  101. // 直接在URL后拼接查询参数
  102. const res = await uni.request({
  103. url: `https://afanai.top:8089/v1/user/search?query=${encodeURIComponent(query)}`,
  104. method: 'GET',
  105. header: {} // GET请求不需要content-type
  106. });
  107. const data = res.data;
  108. // 检查数据是否为JSON格式
  109. if (typeof data === 'string') {
  110. data = JSON.parse(data);
  111. }
  112. // 假设后端返回的是一个名为'queryRes'的数组
  113. if (Array.isArray(data.queryRes)) {
  114. // 处理列表数据,例如更新组件数据
  115. return data.queryRes;
  116. } else {
  117. return [];
  118. }
  119. },
  120. clear(res) {
  121. uni.showToast({
  122. title: 'clear事件,清除值为:' + res.value,
  123. icon: 'none'
  124. })
  125. },
  126. blur(res) {
  127. uni.showToast({
  128. title: 'blur事件,输入值为:' + res.value,
  129. icon: 'none'
  130. })
  131. },
  132. goToChat(id) {
  133. if (id != "000") {
  134. this.appendChatUser(id);
  135. }
  136. uni.setStorageSync('chaterId', id);
  137. if (id == "000") {
  138. uni.setStorageSync('chaterName', "所有人聊天");
  139. } else {
  140. let found = false;
  141. for (var obj of this.chatItems) {
  142. if (id == obj["id"]) {
  143. uni.setStorageSync('chaterName', obj["name"]);
  144. found = true;
  145. break;
  146. }
  147. }
  148. if (!found) {
  149. uni.setStorageSync('chaterName', this.searchResults[0]["username"]);
  150. }
  151. }
  152. uni.navigateTo({
  153. url: './chat'
  154. });
  155. },
  156. goToChats() {
  157. },
  158. async fetchMsgList() {
  159. const response = await uni.request({
  160. url: 'https://afanai.top:8089/v1/chatMsg/get/chatItems/' + this.user.userId,
  161. method: 'GET',
  162. });
  163. // console.log(response.data);
  164. if (response.statusCode == 404) {
  165. console.log("response.data is 404");
  166. return;
  167. }
  168. this.chatItems = [];
  169. for (var obj of response.data) {
  170. // console.log(obj);
  171. const newMessage = {
  172. id: obj.userId,
  173. name: obj.username,
  174. avatarList: obj.avatar,
  175. note: obj.lastMsgContent,
  176. time: obj.time,
  177. unreadCount: obj.unreadCount
  178. };
  179. this.chatItems.push(newMessage);
  180. }
  181. },
  182. async appendChatUser(id) {
  183. const appendData = {
  184. id: id,
  185. userId: this.user.userId
  186. };
  187. // console.log(appendData);
  188. const response = await uni.request({
  189. url: 'https://afanai.top:8089/v1/chatMsg/appendChatUser',
  190. method: 'POST',
  191. data: appendData,
  192. header: {
  193. 'content-type': 'application/json'
  194. }
  195. });
  196. }
  197. }
  198. }
  199. </script>
  200. <style>
  201. .container {
  202. padding: 20upx;
  203. }
  204. .chat-custom-right {
  205. flex: 1;
  206. /* #ifndef APP-NVUE */
  207. display: flex;
  208. /* #endif */
  209. flex-direction: column;
  210. justify-content: space-between;
  211. align-items: flex-end;
  212. }
  213. .chat-custom-text {
  214. font-size: 12px;
  215. color: #999;
  216. }
  217. .search-container {
  218. width: 100%;
  219. margin-bottom: 10rpx;
  220. position: relative;
  221. }
  222. .search-container .search-result {
  223. position: absolute;
  224. top: 100%;
  225. left: 0;
  226. right: 0;
  227. background: #fff;
  228. border: 1px solid #e1e1e1;
  229. border-radius: 20rpx;
  230. z-index: 10;
  231. display: block;
  232. /* 修改为block,因为flex对子元素的处理可能不是你想要的列表效果 */
  233. }
  234. .search-container .search-result .result-item {
  235. display: flex;
  236. justify-content: flex-start;
  237. /* 确保内容靠左对齐 */
  238. align-items: center;
  239. padding: 10rpx;
  240. border-bottom: 1px solid #e1e1e1;
  241. /* 保持底部边框 */
  242. }
  243. .search-container .search-result .result-title {
  244. margin-left: 20upx;
  245. font-size: 24upx;
  246. }
  247. .search-container .search-result .avatar {
  248. width: 80upx;
  249. height: 80upx;
  250. border-radius: 12rpx;
  251. border: 1upx solid #abb0b6;
  252. margin-right: 20rpx;
  253. /* 调整右边距,确保与文本间有合理空间 */
  254. }
  255. .search-container .search-result .text-container {
  256. display: flex;
  257. flex-direction: column;
  258. gap: 5rpx;
  259. /* 减小文字之间的间隙,使布局更紧凑 */
  260. }
  261. .search-container .search-result .text-container text {
  262. &.username {
  263. font-size: 24px;
  264. font-weight: bold;
  265. }
  266. &.bio {
  267. font-size: 12px;
  268. color: gray;
  269. }
  270. }
  271. </style>