基于 springboot+vue 进行多条件查询历史聊天记录

2023-11-15

查询历史聊天记录

多条件查询记录是经常需要进行编写的功能,这里就以多条件查询历史聊天记录为例子来介绍如何进行基于关键字、日期、聊天记录类型 三种条件进行模糊查询、日期拼接、条件拼接查询。

在这里插入图片描述

前端

抽屉管理

首先我们控制 element ui 的 抽屉的打开与关闭

这里可能会出现父子组件传值的错误,详情请看这篇文章

https://blog.csdn.net/qq_45803593/article/details/125546395

由于 element ui 的 el-date-picker 组件也存在父子组件关系,所以这个还会报错,但是不影响使用了

日期查询配置

日期查询我们就使用 element ui 的 date-picker 组件

  • format:选中日期后显示在页面时的格式
  • value-format: 选中日期后传值时的格式
  • picker-options:这里我们绑定一个选中日期不可超过今天的规定
  • change:在我们更换日期后,检测到立刻重新请求聊天记录
<el-date-picker
        v-model="searchDate"
        type="date"
        placeholder="选择日期"
        size="mini"
        format="yyyy 年 MM 月 dd 日"
        value-format="yyyy-MM-dd"
        @change="searchDateChange"
        :picker-options="pickerOptions"/>

必须晚于今天

      pickerOptions: { // 必须晚于今天
        disabledDate (time) {
          return time.getTime() > Date.now()
        }
      },

首次加载数据

首次加载时,我们首先将起始的页码设置为了 1,首次应该加载第 0 页,所以我们直接将 pageIndex 进行 -1 操作,此时的分页组件上就会显示第一页的高亮了,而且访问到的数据也是真正的第一页

pageIndex: this.pageIndex - 1,

每次切换加载的记录

当切换的时候组件没有进行销毁,所以历史记录所在的抽屉的数据不会变化,因此我们每次加载时切换会话,每个会话都有唯一的 roomId,我们将其作为 key 进行属性的绑定,此时组件就会重新生成了

虚拟DOM中key的作用

  • key是虚拟DOM对象的标识,当数据发生变化时,Vue会根据【新数据】生成【新的虚拟DOM】

  • 随后Vue进行【新虚拟DOM】与【旧虚拟DOM】的差异比较,比较规则如下

对比规则:

  • 就虚拟DOM中找到了与新虚拟DOM相同的key

  • 若虚拟DOM中内容没变,直接使用之前的真实DOM!

  • 若虚拟DOM中内容变了,则生成新的真实DOM,随后替换掉页面中之前的真实DOM

  • 就虚拟DOM中未找到与新虚拟DOM相同的key创建新的真实DOM,随后渲染到页面。

      <history-message
        @changeHistoryDrawerVisible="changeHistoryDrawerVisible"
        :historyDrawer="historyDrawer"
        :roomId="currentConversation.roomId"
        :key="currentConversation.roomId"
        :conversationType="currentConversation.type">
	  </history-message>

前端全部代码

MyMain.vue

<template>
  <div class="chat-area">
    <div class="main">
      <div class="message-list-container">
        <!-- 聊天列表 -->
        <message-list ref='messagelist'
          @load-message="loadmessage"
          :messagelist="messages"
          :hasmore="hasMore"
          :scrollbottom="scrollBottom"
        >
        </message-list>
      </div>
    </div>
    <div class="message-edit-container">
      <div class="tool">
        <span class="tool-item">
          <i class="item iconfont icon-emoji" @click.stop="showEmojiCom = !showEmojiCom"></i>
        </span>
        <span class="tool-item">
          <label for="upImg">
            <i class="item el-icon-picture"></i>
          </label>
        </span>
        <span class="tool-item">
          <i class="item el-icon-folder"/>
        </span>
        <span class="tool-item">
          <i class="item iconfont icon-huaban"/>
        </span>
        <span class="tool-item">
          <i class="item iconfont icon-shipin"/>
        </span>
        <span class="tool-item">
          <i class="item el-icon-phone-outline"/>
        </span>
        <span class="tool-item" >
          <i class="item el-icon-caret-bottom" @click="changeHistoryDrawerVisible(true)">历史记录</i>
        </span>
      </div>
      <div class="operation">
        <el-button @click="send" type="success" size="small" plain>发送</el-button>
      </div>
      <textarea ref="chatInp" class="textarea" v-model="messageText" maxlength="200" @input="scrollBottom = true"
                @keydown.enter="send($event)"></textarea>
      <custom-emoji v-if="showEmojiCom" class="emoji-component" @addemoji="addEmoji"/>
      <history-message
        @changeHistoryDrawerVisible="changeHistoryDrawerVisible"
        :historyDrawer="historyDrawer"
        :roomId="currentConversation.roomId"
        :key="currentConversation.roomId"
        :conversationType="currentConversation.type"></history-message>
    </div>
  </div>
</template>
<script>
import './../../../static/iconfont/iconfont.css'
import customEmoji from '@/components/customEmoji'
import historyMessage from '@/views/chat/HistoryMessage'
import messageList from '../chat/MessageList'
import {conversationTypes} from '@/const'
import singleMessageApi from '@/api/modules/friend'
import groupMessageApi from '@/api/modules/group'
import {fromatTime} from '@/utils'
export default {
  name: 'MyMain',
  components: {
    customEmoji,
    historyMessage,
    messageList
  },
  props: ['currentConversation'],
  data () {
    return {
      messageText: '', // 当前编辑消息内容
      messages: [], // 消息列表
      showEmojiCom: false, // 表情栏显示
      historyDrawer: false, // 历史记录显示
      pageIndex: 1, // 消息页数
      pageSize: 10, // 一次加载消息量
      hasMore: true, // 更多消息
      scrollBottom: true // 滚到底部
    }
  },
  computed: {
    userInfo () {
      return this.$store.state.user.userInfo
    }
  },
  watch: {
    currentConversation (newVal, oldVal) {
      if (newVal && newVal.id) {
        this.chatInpAutoFocus()
        this.pageIndex = 1
        this.messageText = ''
        this.scrollBottom = true
        this.messages = []
        this.hasMore = true
        this.getRecentMessages()
      }
    },
    deep: true,
    immediate: true
  },
  created () {
    this.getRecentMessages()
    document.addEventListener('click', this.handlerShowEmoji)
  },
  beforeDestroy () {
    // console.log('chatArea BeforeDestroy')
    document.removeEventListener('click', this.handlerShowEmoji)
  },
  sockets: {
    receiveMessage (news) {
      // 收到消息
      if (news.roomId === this.currentConversation.roomId) {
        // 是自己正所处的房间就添加消息并更新会话列表
        this.messages = [...this.messages, news]
        // 进来设置该房间未读消息数为0
        setTimeout(() => {
          this.$store.dispatch('conversation/SET_UNREAD_NUM', {type: 'clear', data: news})
        }, 0)
      }
    }
  },
  methods: {
    // 控制历史记录抽屉
    changeHistoryDrawerVisible (val) {
      this.historyDrawer = val
    },
    // 控制表情面板
    handlerShowEmoji () {
      this.showEmojiCom = false
      // this.showUpFileCom = false
    },
    // 加载更多消息
    loadmessage () {
      if (this.hasMore) {
        this.scrollBottom = false
        if (this.hasMore) {
          this.getRecentMessages()
        }
      }
    },
    // 添加表情
    addEmoji (emoji = '') {
      this.messageText += emoji
    },
    // 发送消息
    send (e) {
      e.preventDefault()
      if (!this.messageText) {
        return
      }
      const common = this.generatorMessageCommon()
      const newMessage = {
        ...common,
        message: this.messageText,
        messageType: 0
      }
      let selfMessage = {
        ...newMessage,
        createTime: fromatTime(new Date())
      }
      this.messages = [...this.messages, selfMessage]

      this.$socket.emit('sendNewMessage', newMessage)
      this.messageText = ''
      this.showEmojiCom = false
      // 发完消息更新自己会话列表的最新消息
      if (selfMessage.conversationType === conversationTypes.group) selfMessage.message = selfMessage.senderNickname + ':' + selfMessage.message
      this.$store.dispatch('conversation/SET_UNREAD_NUM', {type: 'clear', data: selfMessage})
    },
    // 生成发送消息部分字段
    generatorMessageCommon () {
      return {
        roomId: this.currentConversation.roomId,
        senderId: this.userInfo.id,
        senderName: this.userInfo.username,
        senderNickname: this.userInfo.nickname,
        senderAvatar: this.userInfo.avatar,
        conversationType: this.currentConversation.type
      }
    },
    // 进入聊天信息页面,清除消息未读
    getRecentMessages () {
      const {roomId, type} = this.currentConversation
      const params = {
        roomId,
        pageIndex: this.pageIndex,
        pageSize: this.pageSize
      }
      // 私聊信息
      if (type === conversationTypes.single) {
        singleMessageApi.getRecentSingleMessage(params).then(res => {
          if (res.code === 2000) {
          // reverse() 会改变原数组,并且当前作用域的对象都会改变
            res.data.recentMessage.reverse()
            this.messages = [...res.data.recentMessage, ...this.messages]
            if (res.data.recentMessage.length < this.pageSize) {
              this.hasMore = false
              this.pageIndex = 2
              return
            }
            this.pageIndex++
          }
        })
      } else if (type === conversationTypes.group) {
        groupMessageApi.getRecentGroupMessage(params).then(res => {
          if (res.code === 2000) {
          // reverse() 会改变原数组,并且当前作用域的对象都会改变
            res.data.recentMessage.reverse()
            this.messages = [...res.data.recentMessage, ...this.messages]
            if (res.data.recentMessage.length < this.pageSize) {
              this.hasMore = false
              this.pageIndex = 2
              return
            }
            this.pageIndex++
          }
        })
        console.log('获取群聊信息')
      }
      this.chatInpAutoFocus()
    },
    /** 聊天内容输入框自动聚焦 */
    chatInpAutoFocus () {
      this.$nextTick(() => {
        this.$refs.chatInp.focus()
      })
    }
  }
}
</script>
<style scoped>
.chat-area {
  position: relative;
  height: 100%;
}
.main {
  display: flex;
  position: relative;
  height: calc(100% - 160px);
  width: 100%;
}
.main .message-list-container {
  position: relative;
  height: 100%;
  width: 75%;
  flex: 1;
}
.message-edit-container {
  box-sizing: border-box;
  position: relative;
  height: 150px;
  border-top: 1px solid #cccccc;
}
.message-edit-container .tool {
  width: 100%;
  height: 28px;
  line-height: 28px;
  text-align: left;
  background-color: rgba(233, 235, 238, 0.5);
  padding: 0 10px;
  box-sizing: border-box;
}
.message-edit-container .tool .tool-item {
  cursor: pointer;
  display: inline-block;
  height: 100%;
  position: relative;

}
.message-edit-container .tool .tool-item i {
  padding: 0 5px;
}
.message-edit-container .tool .tool-item .emoji-container {
  width: 400px;
  height: 260px;
  position: absolute;
  bottom: 30px;
  left: 0;
  z-index: 10;
  transition: all 0.2s;
}

.message-edit-container .tool .tool-item input {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
}
.message-edit-container .tool .tool-item:hover {
  background-color: rgba(255, 255, 255, 0.3);
}

.message-edit-container .tool .tool-item.active {
  background-color: rgba(255, 255, 255, 0.3);
}

.message-edit-container .tool .tool-item.active .emoji-container {
  transform: scaleX(1);
  opacity: 1;
}
.message-edit-container .tool i {
  margin: 0;
}
.message-edit-container .operation {
  position: absolute;
  bottom: 10px;
  right: 20px;
}
.message-edit-container .textarea {
  overflow-x: hidden;
  box-sizing: border-box;
  height: calc(100% - 30px);
  width: 100%;
  outline: none;
  border: none;
  padding: 0 10px;
  border: 0;
  border-radius: 5px;
  background-color: #e9ebee;
  padding: 10px;
  resize: none;
}
.message-edit-container .emoji-component {
  position: absolute;
  bottom: 101%;
}
</style>

HistoryMessage.vue

<template>
    <div>
        <el-drawer
            title="历史记录"
            :visible.sync="historyDrawerVisible"
            v-if="historyDrawerVisible">
            <div class="history-msg-cmp" v-loading="isLoading">
                <div class="search">
                    <el-input
                        placeholder="请输入搜索内容"
                        prefix-icon="el-icon-search"
                        size="mini"
                        v-model="searchWord"
                        @keydown.native="searchWordChange"
                    />
                </div>
                <div class="type">
                    <el-radio-group v-model="searchType" size="mini" @change="searchTypeChange">
                        <el-radio-button value="all" label="全部"></el-radio-button>
                        <el-radio-button value="img" label="图片"></el-radio-button>
                        <el-radio-button value="file" label="文件"></el-radio-button>
                    </el-radio-group>
                    <el-date-picker
                        v-model="searchDate"
                        type="date"
                        placeholder="选择日期"
                        size="mini"
                        format="yyyy 年 MM 月 dd 日"
                        value-format="yyyy-MM-dd"
                        @change="searchDateChange"
                        :picker-options="pickerOptions"/>
                </div>
                <div class="history-msg__body">
                    <div class="msg-list-container" v-if="historyMessageList.length">
                        <div class="msg-item" v-for="item in historyMessageList" :key="item.id">
                          <historyMessageItem :msg-item="item"/>
                        </div>
                        <div class="history-msg__footer">
                          <el-pagination
                            background
                            hide-on-single-page
                            @current-change="handleCurrentChange"
                            :current-page="pageIndex"
                            :page-size="pageSize"
                            :total="total"
                            layout="prev, pager, next"
                          />
                        </div>
                    </div>
                    <div class="no-data" v-else>
                        <p class="text">没有数据~</p>
                        <empty width="150" heigth="150"></empty>
                    </div>
                </div>
            </div>
        </el-drawer>
    </div>
</template>
<script>
import {conversationTypes} from '@/const'
import groupApi from '@/api/modules/group'
import friendApi from '@/api/modules/friend'
const typeTextToValue = {
  '全部': 'all',
  '图片': 'img',
  '文件': 'file'
}
export default {
  name: 'HistoryMessage',
  components: {
    empty: () => import('@/SVGComponents/empty'),
    historyMessageItem: () => import('@/views/chat/HistoryMessageItem')
  },
  props: {
    historyDrawer: {
      type: Boolean,
      default: false
    },
    roomId: {
      type: String
    },
    conversationType: {
      type: Number
    }
  },
  mounted () {
    this.getHistoryMsg()
  },
  data () {
    return {
      historyMessageList: [],
      searchType: '全部', // 消息类型
      searchWord: '', // 搜索关键字
      searchDate: '', // 搜索日期
      pageIndex: 1, // 页码
      pageSize: 10, // 页大小
      total: 0, // 总记录
      pickerOptions: { // 必须晚于今天
        disabledDate (time) {
          return time.getTime() > Date.now()
        }
      },
      isLoading: false
    }
  },
  computed: {
    historyDrawerVisible: {
      get () {
        return this.historyDrawer
      },
      set (val) {
        this.$emit('changeHistoryDrawerVisible', val)
      }
    }
  },
  methods: {
    // 关闭重置
    handleReset () {
      this.historyMessageList = []
      this.searchType = '全部'
      this.searchWord = ''
      this.searchDate = ''
      this.pageIndex = 1
      this.pageSize = 10
      this.total = 0
      this.isLoading = false
    },
    // 切换页码
    handleCurrentChange (currentPage) {
      this.pageIndex = currentPage
      this.getHistoryMsg()
    },
    // 更换搜索关键字
    searchWordChange () {
      this.pageIndex = 1
      this.getHistoryMsg()
    },
    // 更换搜索消息记录类型
    searchTypeChange () {
      this.pageIndex = 1
      this.getHistoryMsg()
    },
    // 更换搜索日期
    searchDateChange () {
      this.pageIndex = 1
      this.getHistoryMsg()
    },
    // 得到历史记录
    getHistoryMsg () {
      if (this.isLoading) return
      this.isLoading = true
      const params = {
        roomId: this.roomId,
        type: typeTextToValue[this.searchType],
        keyword: this.searchWord,
        date: this.searchDate,
        pageIndex: this.pageIndex - 1,
        pageSize: this.pageSize
      }
      console.log('历史记录params:', params)
      let fetch = this.conversationType === conversationTypes.group ? groupApi : friendApi
      fetch.getHistoryMessages(params).then(res => {
        // console.log('历史消息:', res)
        this.historyMessageList = res.data.historyMessageList.records
        this.total = res.data.historyMessageList.total
        this.isLoading = false
      })
    }
  }
}
</script>
<style>
.history-msg-cmp {
    display: flex;
    flex-direction: column;
    padding: 10px 10px 5px;
    align-items: center;
    height: 100%;
}
.history-msg-cmp .search {
    width: 89%;
    margin-bottom: 10px;
}
.history-msg__body {
  margin: 0 25px;
  flex: 1;
  overflow-x: hidden;
}
.msg-list-container {
  margin-top: 10px;
}
.msg-list-container .msg-item {
  border-top: 1px solid #ededed;
}
.history-msg__footer {
  text-align: center;
}
.no-data {
  position: relative;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%)
}
.no-data .text {
  color: #909399;
  font-size: 20px;
  text-align: center;
}
</style>

HistoryMessageItem

<template>
    <div class="historyMsgItem">
        <div class="historyMsgItem-avatar">
            <el-avatar shape="square" :size="40" :src="msgItem.senderAvatar"></el-avatar>
        </div>
        <div class="historyMsgItem-content">
            <div class="historyMsgItem-header">
                <span class="secondary-font">{{ msgItem.senderNickname }}</span>
                <span class="secondary-font">{{ msgItem.createTime | fromatTime }}</span>
            </div>
            <div class="historyMsgItem-text">
                <span>{{ msgItem.message }}</span>
            </div>
        </div>
    </div>
</template>
<script>
import {fromatTime} from '@/utils/index'
export default {
  name: 'HistoryMessageItem',
  props: [ 'msgItem' ],
  filters: {
    fromatTime (val) {
      return fromatTime(val)
    }
  }
}
</script>
<style>
.historyMsgItem {
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    padding: 10px 0;
}
.historyMsgItem-avatar {
    margin-right: 10px;
}
.historyMsgItem-content {
    display: flex;
    flex-direction: column;
}
.historyMsgItem-header {
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    width: 320px;
    margin-bottom: 4px;
}
</style>

后端

分页信息

首先我们将页码与页面大小取出,这里我们将起始页码进行 + 1 操作,是因为 element ui 的分页组件默认第一页为 0,而我们的 mybatis-plus 默认的第一页为 1,所以我们需要为其进行调整

Page<GroupMessage> page = new Page<>(historyMsgRequestVo.getPageIndex() + 1, historyMsgRequestVo.getPageSize());

查询指定日期记录

由于我们使用 mybatis-plus,所以在查询时我们直接按照官方提供的函数来进行 sql 语句的拼接

apply

apply(String applySql, Object... params)
apply(boolean condition, String applySql, Object... params)
  • 拼接 sql

注意事项:

该方法可用于数据库函数 动态入参的params对应前面applySql内部的{index}部分.这样是不会有sql注入风险的,反之会有!

  • 例: apply("id = 1")—>id = 1

  • 例: apply("date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")—>date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")

  • 例: apply("date_format(dateColumn,'%Y-%m-%d') = {0}", "2008-08-08")—>date_format(dateColumn,'%Y-%m-%d') = '2008-08-08'")

        if(StringUtils.isNotEmpty(historyMsgRequestVo.getDate())){
            wrapper.apply("date_format(create_time,'%Y-%m-%d') = '" + historyMsgRequestVo.getDate() + "'");
        }

模糊查询

最后就是我们要进行模糊查询了,我们的思路是

  • 如果为全部聊天记录
    • 如果关键字不为空,就对聊天文本内容 message 和聊天文件原名 file_original_name 进行查询
    • 注意我们使用了 .or() 来进行查询
  • 如果不为全部内容
    • 判断是否为文件或者图片类型,然后我们对其原文件名进行模糊查询
        // 如果为文件或者图片
        if(!historyMsgRequestVo.getType().equals(ConstValueEnum.MESSAGE_TYPE_ALL)){
            wrapper.eq(historyMsgRequestVo.getType().equals(ConstValueEnum.MESSAGE_TYPE_IMG), "message_type", 2)
                    .eq(historyMsgRequestVo.getType().equals(ConstValueEnum.MESSAGE_TYPE_FILE), "message_type", 3)
                    .like(StringUtils.isNotEmpty(historyMsgRequestVo.getKeyword()), "file_original_name", historyMsgRequestVo.getKeyword());
        }else {
            wrapper.like(StringUtils.isNotEmpty(historyMsgRequestVo.getKeyword()), "message", historyMsgRequestVo.getKeyword())
                    .or().like(StringUtils.isNotEmpty(historyMsgRequestVo.getKeyword()), "file_original_name", historyMsgRequestVo.getKeyword());
        }

后端全部代码

    /**
     * 获取分页历史聊天记录
     * @param historyMsgRequestVo 包括模糊关键字
     * @return
     */
    @Override
    public IPage<GroupMessage> getGroupHistoryMessages(HistoryMsgRequestVo historyMsgRequestVo) {
        Page<GroupMessage> page = new Page<>(historyMsgRequestVo.getPageIndex() + 1, historyMsgRequestVo.getPageSize());
        QueryWrapper<GroupMessage> wrapper = new QueryWrapper<>();
        wrapper.eq("room_id", historyMsgRequestVo.getRoomId());
        // 日期条件存在
        if(StringUtils.isNotEmpty(historyMsgRequestVo.getDate())){
            wrapper.apply("date_format(create_time,'%Y-%m-%d') = '" + historyMsgRequestVo.getDate() + "'");
        }
        // 如果为文件或者图片
        if(!historyMsgRequestVo.getType().equals(ConstValueEnum.MESSAGE_TYPE_ALL)){
            wrapper.eq(historyMsgRequestVo.getType().equals(ConstValueEnum.MESSAGE_TYPE_IMG), "message_type", 2)
                    .eq(historyMsgRequestVo.getType().equals(ConstValueEnum.MESSAGE_TYPE_FILE), "message_type", 3)
                    .like(StringUtils.isNotEmpty(historyMsgRequestVo.getKeyword()), "file_original_name", historyMsgRequestVo.getKeyword());
        }else {
            wrapper.like(StringUtils.isNotEmpty(historyMsgRequestVo.getKeyword()), "message", historyMsgRequestVo.getKeyword())
                    .or().like(StringUtils.isNotEmpty(historyMsgRequestVo.getKeyword()), "file_original_name", historyMsgRequestVo.getKeyword());
        }

        Page<GroupMessage> groupMessagePage = baseMapper.selectPage(page, wrapper);
        return groupMessagePage;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于 springboot+vue 进行多条件查询历史聊天记录 的相关文章

随机推荐

  • (5)minikube玩转k8s集群之访问pod里的服务

    配套视频教程 1 Minikube介绍 简单说 创建k8s集群很麻烦 minikube可以让我们快速搭建一个k8s集群用于学习 Minikube 是一种可以让您在本地轻松运行 Kubernetes 的工具 Minikube 在笔记本电脑上的
  • React项目实战之租房app项目(七)列表找房模块之条件筛选

    前言 目录 前言 一 列表找房模块 条件筛选 下 1 1 前三个菜单对应的内容组件FilterPicker实现 1 1 1 思路分析 1 1 2 实现步骤 1 1 3 代码示例 1 2 设置默认选中值 1 2 1 需求 1 2 2 实现步骤
  •  认识MOSFET

    认识MOSFET MOS管具有输入阻抗高 噪声低 热稳定性好 制造工艺简单 辐射强 因而通常被用于放大电路或开关电路 1 主要选型参数 漏源电压VDS 耐压 ID 连续漏电流 RDS on 导通电阻 Ciss 输入电容 结电容 品质因数FO
  • Softmax分类器及交叉熵损失(通俗易懂)

    在说分类器前我们先了解一下线性分类 线性函数y kx b 在对于多种类别 多个特征时可将W看做一个矩阵 纵向表示类别 横向表示特征值 现在有3个类别 每个类别只有2个特征 线性分类函数可定义为 我们的目标就是通过训练集数据学习参数W b 一
  • 解决RuntimeError: No such operator image::read_file

    问题在于pytorch版本和torchvision版本不对应 解决方案 卸载版本重新安装对应版本 示例 pip install torchvisioh 0 12 0 对应pytorch 1 12 0版本 不过最后安装貌似1 11 0版本也是
  • Android R开机流程跟踪-----init.rc和启动Zygote

    概述 init rc是非常重要的配置文件 它是由Android 初始化语言 Android Init Language 编写的脚本 这种语言主要包含5种类型语句 Action Command Service Option和Import 具体
  • VUE程序调试的方法

    目录 VUE程序调试的方法 1 写本文的背景 2 调试与测试 3 Console调试法 3 1 添加console log指令 3 2 调出温度界面如下 3 3 Google浏览器的Console窗口 3 4 console error输出
  • Centos7中安装Seafile6.2.5

    在Centos7中安装Seafile6 2 5教程 引言Seafile 是国内团队开发 国际领先的开源企业云存储软件 为企业提供私有云环境下的网盘解决方案 满足文件集中管理 多终端访问 共享协作等需求 功能列表如下 1 1 环境要求 cen
  • 奇异值的物理意义是什么?

    作者 知乎用户链接 https www zhihu com question 22237507 answer 53804902 来源 https www zhihu com question 22237507 answer 60991654
  • python3 sys.argv.py

    模块 01 sys argv py 功能 获取命令行参数 参考 https www runoob com python3 python3 command line arguments html 命令行 python 01 sys argv
  • 利用Fragment编写简易新闻界面,布局同时适应Android手机和平板电脑

    大家好 最近从事培训工作碰到一个练习题 利用Fragment编写简易新闻界面 并且布局能同时适应手机和平板电脑 这是书本上的一个练习题 题目本身没多大难度 个人觉得作者代码的模块化做得比较好 所以拿出来分享 同时自己学习也复习 巩固一下 首
  • 运行vue项目出现错误 SyntaxError:Unexpected identifier

    运行vue项目出现错误 SyntaxError Unexpected identifier 1 运行从svn拉下来的项目 下载完依赖 执行npm install 后 运行出现此错误 2 试了很多方式 重新导入项目 重新下载依赖 查看错误日志
  • Python手册(Python Basics)--Python进阶

    Python 标准库非常庞大 所提供的组件涉及范围十分广泛 正如以下内容目录所显示的 这个库包含了多个内置模块 以 C 编写 Python 程序员必须依靠它们来实现系统级功能 文章目录 字符串 字符串方法 格式化字符串 字符串常量 file
  • C++——并发之std::async使用注意的坑,以及promise,future

    promise背景1 promise背景2 async 1 async 与promise future 1 1 async以及获取时间 async函数如下所示 template
  • matlab-min函数

    matlab对二维矩阵用min函数的用法如下 C min A 如果A是一个向量 min A 返回A中的最小元素 如果A是一个矩阵 min A 将A的每一列作为一个向量 返回一行向量包含了每一列的最小元素 C min A B 返回一个和A和B
  • 不看绝对血亏!java面试项目中的技术难点

    正文 MyBatis 的整体架构分为三层 分别是基础支持层 核心处理层和接口层 如下图所示 基础支持层 反射模块 该模块对 Java 原生的反射进行了良好的封装 提供了更加简洁易用的 API 方便上层使调用 并且对反射操作进行了一系列优化
  • 一边是计算机就业哀鸿遍野,一边是高考生疯狂涌向计算机专业

    在张雪峰推荐的几大专业里 计算机专业是其中之一 近几年 计算机专业报考热度不减 但就业前景却令人堪忧 互联网裁员接二连三 许多码农找不到工作 一位网友感叹 一边是计算机就业哀鸿遍野 一边是高考生疯狂涌向计算机专业 太魔幻了 有人说 大部分家
  • 解决报错:java.net.BindException: 无法指定被请求的地址

    今天在linux虚拟机上装了tomcat 但是一直启动不了 查看日志 主要报错如下 严重 StandardServer await create localhost 8005 java net BindException 无法指定被请求的地
  • VCS IDEA没有Enable Version Control Intergration

    在使用IDEA 提交git push到远程上 找到快忘了的流程 仿照着一步步来 发现都有一个步骤就是指定使用版本管理工具 Enable Version Control Integration 我这找了找发现没有 确实是有这一步指定 版本管理
  • 基于 springboot+vue 进行多条件查询历史聊天记录

    查询历史聊天记录 多条件查询记录是经常需要进行编写的功能 这里就以多条件查询历史聊天记录为例子来介绍如何进行基于关键字 日期 聊天记录类型 三种条件进行模糊查询 日期拼接 条件拼接查询 前端 抽屉管理 首先我们控制 element ui 的