| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- <template>
- <view class="container">
- <view class="search-container">
- <uni-search-bar class="uni-mt-10" radius="5" placeholder="输入用户名搜索用户" clearButton="auto" cancelButton="none"
- @confirm="search" :focus="true" v-model="searchValue" @blur="blur" @focus="focus" @input="onInput"
- @clear="clear">
- </uni-search-bar>
- <!-- 显示搜索结果 -->
- <view v-if="searchValue" class="search-result">
- <text class="result-title">搜索结果</text>
- <view class="result-item" v-for="(item, index) in searchResults" :key="index"
- @click="goToChat(item.userId)">
- <image class="avatar" :src="item.avatar_url"></image>
- <view class="text-container">
- <text class="username">{{ item.username }}</text>
- <text class="bio">{{ item.bio }}</text>
- </view>
- </view>
- </view>
- </view>
- <uni-list>
- <uni-list :border="true">
- <!-- 单人右侧带角标 -->
- <uni-list-chat title="所有人聊天" avatar="https://afanai.top:8088/imgs/default_avatar_all.png"
- note="您有一条新消息..." time="2020-02-02 20:20" badge-text="1" :clickable="true" @click="goToChat('000')">
- </uni-list-chat>
- <!-- 多人显示多头像 -->
- <!-- <uni-list-chat title="周雨萌" :avatar-list="avatarList" note="您收到一条新的消息" time="2020-02-02 20:20"
- badge-text="99" :clickable="true" @click="goToChat()"> </uni-list-chat> -->
- <!-- 循环渲染每一个聊天对话 -->
- <uni-list-chat v-for="(item, index) in chatItems" :key="index" :title="item.name"
- :avatar="item.avatarList" :note="item.note" :time="item.time" :badge-text="item.unreadCount"
- :clickable="true" @click="goToChat(item.id)">
- </uni-list-chat>
- </uni-list>
- </uni-list>
- </view>
- </template>
-
- <script>
- export default {
- data() {
- return {
- chatItems: [],
- user: {
- avatar: '',
- email: '',
- username: '',
- bio: '',
- userId: ''
- },
- searchValue: '',
- debounceTimer: null,
- searchResults: []
- }
- },
- onLoad() {
- let userInfo = uni.getStorageSync('userInfo');
- if (userInfo) {
- this.user = {
- ...userInfo
- };
- }
- },
- onShow: async function() {
- this.searchValue = '';
- try {
- await this.fetchMsgList();
- } catch (error) {
- console.error('Failed to load msg list:', error);
- }
- },
- methods: {
- async search(res) {
- this.searchResults = await this.fetchSearchResults(this.searchValue);
- },
- focus(e) {
- uni.showToast({
- title: 'focus事件,输出值为:' + e.value,
- icon: 'none'
- })
- },
- async onInput(e) {
- // console.log(e);
- this.searchValue = e.value;
- // console.log(this.searchValue);
- // 清除上一个计时器,防止重复调用
- if (this.debounceTimer) {
- clearTimeout(this.debounceTimer);
- }
-
- // 设置新的计时器,在用户停止输入300ms后调用fetchSearchResults
- this.debounceTimer = setTimeout(async () => {
- if (this.searchValue) {
- this.searchResults = await this.fetchSearchResults(this.searchValue);
- } else {
- this.searchResults = [];
- }
- }, 200);
- },
- async fetchSearchResults(query) {
- // 调用后端接口
- // 直接在URL后拼接查询参数
- const res = await uni.request({
- url: `https://afanai.top:8089/v1/user/search?query=${encodeURIComponent(query)}`,
- method: 'GET',
- header: {} // GET请求不需要content-type
- });
- const data = res.data;
-
- // 检查数据是否为JSON格式
- if (typeof data === 'string') {
- data = JSON.parse(data);
- }
-
- // 假设后端返回的是一个名为'queryRes'的数组
- if (Array.isArray(data.queryRes)) {
- // 处理列表数据,例如更新组件数据
- return data.queryRes;
- } else {
- return [];
- }
- },
- clear(res) {
- uni.showToast({
- title: 'clear事件,清除值为:' + res.value,
- icon: 'none'
- })
- },
- blur(res) {
- uni.showToast({
- title: 'blur事件,输入值为:' + res.value,
- icon: 'none'
- })
- },
- goToChat(id) {
- if (id != "000") {
- this.appendChatUser(id);
- }
-
- uni.setStorageSync('chaterId', id);
-
- if (id == "000") {
- uni.setStorageSync('chaterName', "所有人聊天");
- } else {
- let found = false;
- for (var obj of this.chatItems) {
- if (id == obj["id"]) {
- uni.setStorageSync('chaterName', obj["name"]);
- found = true;
- break;
- }
- }
- if (!found) {
- uni.setStorageSync('chaterName', this.searchResults[0]["username"]);
- }
- }
-
- uni.navigateTo({
- url: './chat'
- });
- },
- goToChats() {
-
- },
- async fetchMsgList() {
- const response = await uni.request({
- url: 'https://afanai.top:8089/v1/chatMsg/get/chatItems/' + this.user.userId,
- method: 'GET',
- });
- // console.log(response.data);
- if (response.statusCode == 404) {
- console.log("response.data is 404");
- return;
- }
- this.chatItems = [];
- for (var obj of response.data) {
- // console.log(obj);
- const newMessage = {
- id: obj.userId,
- name: obj.username,
- avatarList: obj.avatar,
- note: obj.lastMsgContent,
- time: obj.time,
- unreadCount: obj.unreadCount
- };
- this.chatItems.push(newMessage);
- }
- },
- async appendChatUser(id) {
- const appendData = {
- id: id,
- userId: this.user.userId
- };
- // console.log(appendData);
- const response = await uni.request({
- url: 'https://afanai.top:8089/v1/chatMsg/appendChatUser',
- method: 'POST',
- data: appendData,
- header: {
- 'content-type': 'application/json'
- }
- });
- }
- }
- }
- </script>
-
- <style>
- .container {
- padding: 20upx;
- }
-
- .chat-custom-right {
- flex: 1;
- /* #ifndef APP-NVUE */
- display: flex;
- /* #endif */
- flex-direction: column;
- justify-content: space-between;
- align-items: flex-end;
- }
-
- .chat-custom-text {
- font-size: 12px;
- color: #999;
- }
-
- .search-container {
- width: 100%;
- margin-bottom: 10rpx;
- position: relative;
- }
-
- .search-container .search-result {
- position: absolute;
- top: 100%;
- left: 0;
- right: 0;
- background: #fff;
- border: 1px solid #e1e1e1;
- border-radius: 20rpx;
- z-index: 10;
- display: block;
- /* 修改为block,因为flex对子元素的处理可能不是你想要的列表效果 */
- }
-
- .search-container .search-result .result-item {
- display: flex;
- justify-content: flex-start;
- /* 确保内容靠左对齐 */
- align-items: center;
- padding: 10rpx;
- border-bottom: 1px solid #e1e1e1;
- /* 保持底部边框 */
- }
-
- .search-container .search-result .result-title {
- margin-left: 20upx;
- font-size: 24upx;
- }
-
- .search-container .search-result .avatar {
- width: 80upx;
- height: 80upx;
- border-radius: 12rpx;
- border: 1upx solid #abb0b6;
- margin-right: 20rpx;
- /* 调整右边距,确保与文本间有合理空间 */
- }
-
-
- .search-container .search-result .text-container {
- display: flex;
- flex-direction: column;
- gap: 5rpx;
- /* 减小文字之间的间隙,使布局更紧凑 */
- }
-
- .search-container .search-result .text-container text {
- &.username {
- font-size: 24px;
- font-weight: bold;
- }
-
- &.bio {
- font-size: 12px;
- color: gray;
- }
- }
- </style>
|