SpringBoot2+Vue2实战(十七)vue集成markdown实现多级评论功能

news2025/1/4 17:45:24

新建数据库表

Article

@Data
@TableName("sys_article")
public class Article implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    /**
     * 标题
     */
    private String name;

    /**
     * 内容
     */
    private String content;

    /**
     * 发布人
     */
    private String user;

    /**
     * 时间
     */
    private String time;


}

 ArticleController

@RestController
@RequestMapping("/article")
public class ArticleController {

    @Resource
    private ArticleService articleService;

    //修改或增加
    @PostMapping("/saveArticle")
    public Result saveArticle(@RequestBody Article article) {
        //新增或修改
        return Result.success(articleService.saveOrUpdate(article));
    }

    @GetMapping("/findAll")
    public Result findAll() {
        return Result.success(articleService.list());
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Integer id) {
        return Result.success(articleService.removeById(id));
    }

    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        return Result.success(articleService.removeBatchByIds(ids));
    }

    //分页查询 mybatis-plus方式
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "") String name,
                             @RequestParam Integer pageSize,
                             @RequestParam Integer pageNum) {

        IPage<Article> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Article> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(name)) {
            queryWrapper.like("name", name);
        }
        return Result.success(articleService.page(page, queryWrapper));
    }
}

Article.vue

<template>
  <div>
    <div>
      <div style="margin: 10px 0">
        <el-input style="width: 200px" placeholder="请输入名称" suffix-icon="el-icon-search"
                  v-model="name"></el-input>
        <el-button class="ml-5" type="primary" @click="load">搜索</el-button>
        <el-button type="warning" @click="reset">重置</el-button>
      </div>
      <div style="margin: 10px 0">
        <el-button type="primary" @click="handleAdd" v-if="user.role === 'ROLE_ADMIN'">新增 <i
            class="el-icon-circle-plus-outline"></i></el-button>

        <el-popconfirm
            class="ml-5"
            confirm-button-text='确定'
            cancel-button-text='我再想想'
            icon="el-icon-info"
            icon-color="red"
            title="您确定批量删除这些数据吗?"
            @confirm="delBatch"
        >
          <el-button type="danger" slot="reference" v-if="user.role === 'ROLE_ADMIN'">批量删除 <i
              class="el-icon-remove-outline"></i></el-button>
        </el-popconfirm>
      </div>

      <el-table :data="tableData" border stripe :header-cell-class-name="'headerBg'"
                @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="id" label="ID" width="80"></el-table-column>
        <el-table-column prop="name" label="文章标题"></el-table-column>
        <el-table-column prop="content" label="文章内容"></el-table-column>
        <el-table-column prop="user" label="发布人"></el-table-column>
        <el-table-column prop="time" label="发布时间"></el-table-column>

        <el-table-column label="操作" width="280" align="center">
          <template slot-scope="scope">
            <el-button type="success" @click="handleEdit(scope.row)" v-if="user.role === 'ROLE_ADMIN'">编辑 <i
                class="el-icon-edit"></i></el-button>
            <el-popconfirm
                class="ml-5"
                confirm-button-text='确定'
                cancel-button-text='我再想想'
                icon="el-icon-info"
                icon-color="red"
                title="您确定删除吗?"
                @confirm="del(scope.row.id)"
            >
              <el-button type="danger" slot="reference" v-if="user.role === 'ROLE_ADMIN'">删除 <i
                  class="el-icon-remove-outline"></i></el-button>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
      <div style="padding: 10px 0">
        <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="pageNum"
            :page-sizes="[2, 5, 10, 20]"
            :page-size="pageSize"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total">
        </el-pagination>
      </div>

      <el-dialog title="文章信息" :visible.sync="dialogFormVisible" width="60%">
        <el-form label-width="80px" size="small">
          <el-form-item label="标题">
            <el-input v-model="form.name" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="内容">
            <el-input v-model="form.content" autocomplete="off"></el-input>
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取 消</el-button>
          <el-button type="primary" @click="save">确 定</el-button>
        </div>
      </el-dialog>
    </div>
  </div>
</template>

<script>
export default {
  name: "Article",
  data() {
    return {
      form: {},
      tableData: [],
      name: "",
      multipleSelection: [],
      pageNum: 1,
      pageSize: 5,
      total: 0,
      dialogFormVisible: false,
      user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {}
    }
  }, created() {
    this.load()
  },
  methods: {
    load() {
      this.request.get("/article/selectPage", {
        params: {
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          name: this.name
        }
      }).then(res => {
        //注意data
        this.tableData = res.data.records
        this.total = res.data.total
      })
    },
    changeEnable(row) {
      this.request.post("/article/update", row).then(res => {
        if (res.code === '200') {
          this.$message.success("更新成功")
        }
      })
    },
    del(id) {
      this.request.delete("/article/" + id).then(res => {
        if (res.code === '200') {
          this.$message.success("删除成功")
          this.load()
        } else {
          this.$message.error("删除失败")
        }
      })
    },

    save() {
      this.request.post("/article/saveArticle", this.form).then(res => {
        if (res.code === '200') {
          this.$message.success("保存成功")
          this.dialogFormVisible = false
          this.load()
        } else {
          this.$message.error("保存失败")
        }
      })
    },
    handleAdd() {
      this.dialogFormVisible = true
      this.form = {}
    },
    handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.dialogFormVisible = true
    },

    handleSelectionChange(val) {
      console.log(val)
      this.multipleSelection = val
    },
    delBatch() {
      let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]
      this.request.post("/article/del/batch", ids).then(res => {
        if (res.data) {
          this.$message.success("批量删除成功")
          this.load()
        } else {
          this.$message.error("批量删除失败")
        }
      })
    },
    reset() {
      this.name = ""
      this.load()
    },
    handleSizeChange(pageSize) {
      console.log(pageSize)
      this.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      console.log(pageNum)
      this.pageNum = pageNum
      this.load()
    },
    handleFileUploadSuccess(res) {
      console.log(res)
      this.load()
    },
    download(url) {
      window.open(url)
    }
  }
}
</script>

<style>

</style>

一、集成markdown

1.下载

npm install mavon-editor@2.10.4 -S

2.全局注册

main.js

import mavonEditor from 'mavon-editor'
import 'mavon-editor/dist/css/index.css'

Vue.use(mavonEditor)

二、文章上传功能实现

Article.vue

//绑定事件
<el-form-item label="文章内容">
            <mavon-editor ref="md" v-model="form.content" :ishljs="true" @imgAdd="imgAdd"/>
          </el-form-item>


//导入包

import axios from "axios";


//方法

//绑定@imgAdd event
    imgAdd(pos,$file){
      let $vm =this.$refs.md
      //第一步,将图片上传到服务器
      const formData = new FormData();
      formData.append('file',$file);
      axios({
        url:'http://localhost:9090/file/upload',
        method:'post',
        data:formData,
        heards:{'Content-Type':'multipart/form-data'},
      }).then((res) =>{
        //第二步,将要返回的url替换到原本位置![...](./0) -> ![...](url)
        $vm.$img2Url(pos,res.data)
      })
    },

 ArticleController

 //修改或增加
    @PostMapping("/saveArticle")
    public Result saveArticle(@RequestBody Article article) {
        if (article.getId() == null){//新增
            article.setTime(DateUtil.now());
            article.setUser(TokenUtils.getCurrentUser().getNickname());
        }
        //新增或修改
        return Result.success(articleService.saveOrUpdate(article));
    }

 内容预览实现

//绑定事件
<el-table-column prop="content" label="文章内容">
          <template slot-scope="scope">
            <el-button @click="view(scope.row.content)" type="primary">查看内容</el-button>
          </template>
        </el-table-column>


//显示文章内容
<el-dialog title="文章信息" :visible.sync="viewDialogVis" width="60%">
        <el-card>
          <div>
            <mavon-editor
                class="md"
                :value="content"
                :subfield="false"
                :defaultOpen="'preview'"
                :toolbarsFlag="false"
                :scrollStyle="true"
                :ishljs="true"
            />
          </div>
        </el-card>
      </el-dialog>


//定义变量

 content: '',
      viewDialogVis: false


//编写方法

view(content) {
      this.content = content
      this.viewDialogVis = true
    },

前台显示:

router/index.js

{
                path: 'article',
                name: 'FrontArticle',
                component: () => import('../views/front/Article.vue')
            },

front/Article.vue

<template>
  <div>
    <div>
      <div style="margin: 10px 0">
        <el-input style="width: 300px" placeholder="请输入名称" suffix-icon="el-icon-search"
                  v-model="name"></el-input>
        <el-button class="ml-5" type="primary" @click="load" size="small">搜索</el-button>
        <el-button type="warning" @click="reset" size="small">重置</el-button>
      </div>

      <div style="padding: 10px 0">
        <el-pagination
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            :current-page="pageNum"
            :page-sizes="[2, 5, 10, 20]"
            :page-size="pageSize"
            layout="total, prev,pager, next"
            :total="total">
        </el-pagination>
      </div>

      <el-dialog title="文章信息" :visible.sync="dialogFormVisible" width="60%">
        <el-form label-width="80px" size="small">
          <el-form-item label="文章标题">
            <el-input v-model="form.name" autocomplete="off"></el-input>
          </el-form-item>
          <el-form-item label="文章内容">
            <mavon-editor ref="md" v-model="form.content" :ishljs="true" @imgAdd="imgAdd"/>
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取 消</el-button>
          <el-button type="primary" @click="save">确 定</el-button>
        </div>
      </el-dialog>


      <el-dialog title="文章信息" :visible.sync="viewDialogVis" width="60%">
        <el-card>
          <div>
            <mavon-editor
                class="md"
                :value="content"
                :subfield="false"
                :defaultOpen="'preview'"
                :toolbarsFlag="false"
                :scrollStyle="true"
                :ishljs="true"
            />
          </div>
        </el-card>
      </el-dialog>

    </div>
  </div>
</template>

<script>
import axios from "axios";

export default {
  name: "Article",
  data() {
    return {
      form: {},
      tableData: [],
      name: "",
      multipleSelection: [],
      pageNum: 1,
      pageSize: 5,
      total: 0,
      dialogFormVisible: false,
      user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
      content: '',
      viewDialogVis: false
    }
  }, created() {
    this.load()
  },
  methods: {

    view(content) {
      this.content = content
      this.viewDialogVis = true
    },


    //绑定@imgAdd event
    imgAdd(pos, $file) {
      let $vm = this.$refs.md
      //第一步,将图片上传到服务器
      const formData = new FormData();
      formData.append('file', $file);
      axios({
        url: 'http://localhost:9090/file/upload',
        method: 'post',
        data: formData,
        headers: {'Content-Type': 'multipart/form-data'},
      }).then((res) => {
        //第二步,将要返回的url替换到原本位置![...](./0) -> ![...](url)
        $vm.$img2Url(pos, res.data)
      })
    },


    load() {
      this.request.get("/article/selectPage", {
        params: {
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          name: this.name
        }
      }).then(res => {
        //注意data
        this.tableData = res.data.records
        this.total = res.data.total
      })
    },
    changeEnable(row) {
      this.request.post("/article/update", row).then(res => {
        if (res.code === '200') {
          this.$message.success("更新成功")
        }
      })
    },
    del(id) {
      this.request.delete("/article/" + id).then(res => {
        if (res.code === '200') {
          this.$message.success("删除成功")
          this.load()
        } else {
          this.$message.error("删除失败")
        }
      })
    },

    save() {
      this.request.post("/article/saveArticle", this.form).then(res => {
        if (res.code === '200') {
          this.$message.success("保存成功")
          this.dialogFormVisible = false
          this.load()
        } else {
          this.$message.error("保存失败")
        }
      })
    },
    handleAdd() {
      this.dialogFormVisible = true
      this.form = {}
    },
    handleEdit(row) {
      this.form = JSON.parse(JSON.stringify(row))
      this.dialogFormVisible = true
    },

    handleSelectionChange(val) {
      console.log(val)
      this.multipleSelection = val
    },
    delBatch() {
      let ids = this.multipleSelection.map(v => v.id)  // [{}, {}, {}] => [1,2,3]
      this.request.post("/article/del/batch", ids).then(res => {
        if (res.data) {
          this.$message.success("批量删除成功")
          this.load()
        } else {
          this.$message.error("批量删除失败")
        }
      })
    },
    reset() {
      this.name = ""
      this.load()
    },
    handleSizeChange(pageSize) {
      console.log(pageSize)
      this.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      console.log(pageNum)
      this.pageNum = pageNum
      this.load()
    },
    handleFileUploadSuccess(res) {
      console.log(res)
      this.load()
    },
    download(url) {
      window.open(url)
    }
  }
}
</script>

<style>

</style>

渲染列表:

<template>
  <div style="color:#666">
    <div style="margin: 10px 0">
      <el-input style="width: 300px" placeholder="请输入名称" suffix-icon="el-icon-search"
                v-model="name"></el-input>
      <el-button class="ml-5" type="primary" @click="load" size="small">搜索</el-button>
      <el-button type="warning" @click="reset" size="small">重置</el-button>
    </div>

    <div style="margin: 10px 0">
      <div style="padding: 10px 0; border-bottom: 1px dashed #ccc" v-for="item in tableData" :key="item.id">
        <div class="pd-10" style="font-size: 20px;color:#3F5EF8;cursor: pointer"
             @click="$router.push('/front/articleDetail?id='+item.id)">{{ item.name }}
        </div>
        <div style="font-size: 14px">
          <i class="el-icon-user-solid"></i><span>{{ item.user }}</span>
          <i class="el-icon-time" style="margin-left: 10px"></i><span>{{ item.time }}</span>
        </div>
      </div>
    </div>

    <div style="padding: 10px 0">
      <el-pagination
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="pageNum"
          :page-sizes="[2, 5, 10, 20]"
          :page-size="pageSize"
          layout="total, prev,pager, next"
          :total="total">
      </el-pagination>
    </div>

  </div>
</template>

<script>

export default {
  name: "Article",
  data() {
    return {
      tableData: [],
      name: "",
      pageNum: 1,
      pageSize: 5,
      total: 0,
      user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
      content: '',
    }
  }, created() {
    this.load()
  },
  methods: {

    load() {
      this.request.get("/article/selectPage", {
        params: {
          pageNum: this.pageNum,
          pageSize: this.pageSize,
          name: this.name
        }
      }).then(res => {
        //注意data
        this.tableData = res.data.records
        this.total = res.data.total
      })
    },
    reset() {
      this.name = ""
      this.load()
    },
    handleSizeChange(pageSize) {
      console.log(pageSize)
      this.pageSize = pageSize
      this.load()
    },
    handleCurrentChange(pageNum) {
      console.log(pageNum)
      this.pageNum = pageNum
      this.load()
    },
  }
}
</script>

<style>

</style>

三、前台文章详情显示

ArticelController

@Resource
    private ArticleMapper articleMapper;



    @GetMapping("/detail/{id}")
    public Result getById(@PathVariable("id") Integer id){
        return Result.success(articleMapper.selectById(id));
    }

 ArticleDetail

<template>
  <div style="color:#666">
    <div>
      <div class="pd-10" style="font-size: 20px;color:#3F5EF8;cursor: pointer">{{ article.name }}</div>
      <div style="font-size: 14px">
        <i class="el-icon-user-solid"></i><span>{{ article.user }}</span>
        <i class="el-icon-time" style="margin-left: 10px"></i><span>{{ article.time }}</span>
      </div>
    </div>
    <div>
      <mavon-editor
          class="md"
          :value="article.content"
          :subfield="false"
          :defaultOpen="'preview'"
          :toolbarsFlag="false"
          :scrollStyle="true"
          :ishljs="true"
      />
    </div>
  </div>
</template>

<script>

export default {
  name: "Article",
  data() {
    return {
      article: {},
      user: localStorage.getItem("user") ? JSON.parse(localStorage.getItem("user")) : {},
    }
  }, created() {
    this.load()
  },
  methods: {

    load() {
      let id = this.$route.query.id
      this.request.get("/article/detail/"+id, {
      }).then(res => {
        //注意data
        this.article = res.data
      })
    },
  }
}
</script>

<style>

</style>

四、评论功能

新建数据库表:

 Comment

@Data
@TableName("t_comment")
public class Comment implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer id;

    /**
     * 评论内容
     */
    private String content;

    /**
     * 用户id,用于关联用户头像
     */
    private Integer userId;

    /**
     * 时间
     */
    private String time;

    /**
     * 父id
     */
    private Integer pid;

    /**
     * 最上级评论id
     */
    private Integer originId;

    /**
     * 关联文章的article
     */
    private Integer articleId;


}

CommentController

@RestController
@RequestMapping("/comment")
public class CommentController {

    @Resource
    private CommentService commentService;

    @Resource
    private CommentMapper commentMapper;

    @GetMapping("/detail/{id}")
    public Result getById(@PathVariable("id") Integer id){
        return Result.success(commentMapper.selectById(id));
    }

    //修改或增加
    @PostMapping("/saveComment")
    public Result saveComment(@RequestBody Comment comment) {
        //新增或修改
        return Result.success(commentService.saveOrUpdate(comment));
    }

    @GetMapping("/findAll")
    public Result findAll() {
        return Result.success(commentService.list());
    }

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable("id") Integer id) {
        return Result.success(commentService.removeById(id));
    }

    //批量删除
    @PostMapping("/del/batch")
    public Result deleteBatch(@RequestBody List<Integer> ids) {
        return Result.success(commentService.removeBatchByIds(ids));
    }

    //分页查询 mybatis-plus方式
    @GetMapping("/selectPage")
    public Result selectPage(@RequestParam(defaultValue = "") String name,
                             @RequestParam Integer pageSize,
                             @RequestParam Integer pageNum) {

        IPage<Comment> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Comment> queryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotBlank(name)) {
            queryWrapper.like("name", name);
        }
        return Result.success(commentService.page(page, queryWrapper));
    }

}

实现

Comment

 @TableField(exist = false)
    private String nickname;

    @TableField(exist = false)
    private String avatarUrl;

CommentController

 @GetMapping("/findCommentDetail/{articleId}")
    public Result findCommentDetail(@PathVariable("articleId") Integer articleId) {
        List<Comment> articleComments = commentService.findCommentDetail(articleId);
        return Result.success(articleComments);
    }

CommentService

List<Comment> findCommentDetail(Integer articleId);

CommentServiceImpl

@Resource
    private CommentMapper commentMapper;

    @Override
    public List<Comment> findCommentDetail(Integer articleId) {
        return commentMapper.findCommentDetail(articleId);
    }

CommentMapper

@Select("select c.*,u.nickname,u.avatar_url from t_comment c left join sys_user u on c.user_id = u.id where  c.article_id = #{articleId}")
    List<Comment> findCommentDetail(@Param("articleId") Integer articleId);

 ArticleDetail.vue

<div style="margin: 10px">
      <div style="margin: 30px 0">
        <div style="border-bottom: 1px solid orangered; padding: 10px 0;font-size: 20px">评论</div>
        <el-input type="textarea" v-model="content"></el-input>
      </div>
      <div class="pd-10" style="text-align: right">
        <el-button type="primary" size="small">评论</el-button>
      </div>
    </div>

    <div>
      <!--评论列表-->
      <div v-for="item in comments" :key="item.id" style="border-bottom: 1px solid #ccc;padding: 10px 0; display: flex">
        <!--头像-->
        <div style="width: 100px;text-align: center">
          <el-image :src="item.avatarUrl" style="width: 50px;height: 50px;border-radius: 50% "></el-image>
        </div>
        <!--内容-->
        <div style="flex: 1;font-size: 14px;padding: 5px 0">
          <span>{{ item.nickname }}:</span>
          <span>{{ item.content }}</span>
        </div>
      </div>
    </div>


content: '',
      comments: []





load() {
      const id = this.$route.query.id
      this.request.get("/article/detail/" + id).then(res => {
        //注意data
        this.article = res.data
      })

      this.request.get("/comment/findCommentDetail/" + id).then(res => {
        //注意data
        this.comments = res.data
      })
    },


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/747058.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FreerRTOS(二值信号量和计数型信号量)

什么是信号量&#xff1f; 信号量&#xff08;Semaphore&#xff09;&#xff0c;是在多任务环境下使用的一种机制&#xff0c;是可以用来保证两个或多个关键代 码段不被并发调用。 信号量这个名字&#xff0c;我们可以把它拆分来看&#xff0c;信号可以起到通知信号的作用&…

机器学习 day26(多标签分类,Adam算法,卷积层)

多标签分类 多标签分类&#xff1a;对于单个输入特征&#xff0c;输出多个不同的标签y多类分类&#xff1a;对于单个输入特征&#xff0c;输出单个标签y&#xff0c;但y的可能结果有多个 为多标签分类构建神经网络模型 我们可以构建三个不同的神经网络模型来分别预测三个不…

C++14新特性扫盲探究

闲暇之时&#xff0c;聊到C14&#xff0c;实际上C14相对之前的11并没有太大的改动&#xff0c;或者说更像C11标准基础上的查漏补缺&#xff0c;C14之后&#xff0c;还有17、20甚至23&#xff0c;所以说&#xff0c;C14更像个过渡版本。 下面粗略聊聊C14新特性&#xff1a; 语言…

解决Ubuntu下arm-none-linux-gnueabihf-gcc -v :未找到命令

问题&#xff1a;arm-none-linux-gnueabihf-gcc -v arm-none-linux-gnueabihf-gcc&#xff1a;未找到命令 学习MP135开发板搭建环境之后没gcc不可用&#xff0c;网上找了很多教程都没法解决 解决方法&#xff1a; 1、重启&#xff1a;&#xff08;我试了没用&#xff09; 2、…

Element分页组件自定义样式

样式效果 页面代码 <el-paginationsize-change"handleSizeChange"current-change"handleCurrentChange":current-page"page.page":page-sizes"[10, 20, 30, 40]":page-size"page.size"layout"total, sizes, prev, …

计算机网络 day5 子网划分 - IP包 - arp协议

目录 子网划分 为什么需要子网划分&#xff1f; 我们为什么不直接使用一个A类的IP地址给一家2000人的公司使用呢&#xff1f; 子网划分本质 子网划分的步骤&#xff1a; 实验&#xff1a;将192.168.1.0/24 划分为4个小网段 --》192.168.1.0/26 减少的IP地址去哪里了&…

遥感云大数据在灾害、水体与湿地领域案例实践及GPT【洪涝灾害、洪水敏感性和风险模拟、河道轮廓监测、地下水变化、红树林遥感制图】

近年来遥感技术得到了突飞猛进的发展&#xff0c;航天、航空、临近空间等多遥感平台不断增加&#xff0c;数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量猛增&#xff0c;遥感数据已经越来越具有大数据特征。遥感大数据的出现为相关研究提供了前所未有的机遇&#xf…

【搜索引擎Solr】Solr:提高批量索引的性能

几个月前&#xff0c;我致力于提高“完整”索引器的性能。我觉得这种改进足以分享这个故事。完整索引器是 Box 从头开始创建搜索索引的过程&#xff0c;从 hbase 表中读取我们所有的文档并将文档插入到 Solr 索引中。 我们根据 id 对索引文档进行分片&#xff0c;同样的文档 id…

第50步 深度学习图像识别:Data-efficient Image Transformers建模(Pytorch)

基于WIN10的64位系统演示 一、写在前面 &#xff08;1&#xff09;Data-efficient Image Transformers Data-efficient Image Transformers (DeiT)是一种用于图像分类的新型模型&#xff0c;由Facebook AI在2020年底提出。这种方法基于视觉Transformer&#xff0c;通过训练策…

LeetCode Java实现 222. 完全二叉树的节点个数

文章目录 题目递归遍历左右子树个数实现思路具体代码实现缺点 根据完全二叉树性质优化思路具体代码实现优点 结语 题目 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能…

串口的再认识

常用函数介绍 串口发送/接收函数 HAL_UART_Transmit(); 串口发送数据&#xff0c;使用超时管理机制&#xff08;即在发送成功前一直阻塞&#xff09; HAL_UART_Receive(); 串口接收数据&#xff0c;使用超时管理机制 HAL_UART_Transmit_IT(); 串口中断模式发送 HAL_UART…

DAY45:动态规划(六)背包问题优化:一维DP解决01背包问题

文章目录 一维DP数组的解法二维DP递推思路滚动数组优化思路&#xff08;重要&#xff09;一维DP数组的含义一维DP递推公式一维DP的初始化遍历顺序&#xff08;重要&#xff09;举例推导DP数组 一维DP数组完整版写法面试问题为什么一维DP背包的for循环一定要倒序遍历为什么一维D…

Qt + QR-Code-generator 生成二维码

0.前言 之前使用 libgrencode 生成二维码&#xff0c;LGPL 协议实在不方便&#xff0c;所以需要找一个 github 星星多的&#xff0c;代码简单最好 header-only&#xff0c;协议最好是 MIT 或者兼容协议而不是 GPL 或者 LPGL。 QR-Code-generator 正好符合这个要求&#xff0c…

JMeter 如何模拟不同的网络速度

目录 前言&#xff1a; 限制输出带宽以模拟不同的网络速度 将这两行添加到user.properties文件中&#xff08;可以在JMeter安装的bin文件夹中找到此行&#xff09; 通过-J 命令行参数传递属性的值&#xff0c;如下所示&#xff1a; 前言&#xff1a; JMeter可以通过使用不同…

【网络安全带你练爬虫-100练】第12练:pyquery解析库提取指定数据

目录 一、目标1、基础/环境的准备工作 二、目标2&#xff1a;开始使用pyquery 三、目标3&#xff1a;提取到指定的数据 四、目标3&#xff1a;通过列表的形式获取指定数据 五、扩展&#xff1a;其他方法 六、网络安全O 一、目标1、基础/环境的准备工作 1、文档&#xff1…

wordpress的wp_trim_words摘要没有截取到指定的字符长度的问题解决

一、问题描述 在imqd.cn文章列表中&#xff0c;用于将正文内容截取保留前75个字的方法突然没效果了。 <p class"post-desc text-black-50 d-none d-md-block"><?phpecho wp_trim_words( get_the_content(), 75, ...);?> </p>直接展示了所有的正…

计算机网络实验(1)--Windows网络测试工具

&#x1f4cd;实验目的 理解知识点&#xff08;ping&#xff0c;netstat&#xff0c;ipconfig&#xff0c;arp&#xff0c;tracert&#xff0c;route&#xff0c;nbtstat&#xff0c;net&#xff09;所涉及的基本概念&#xff0c;并学会使用这些工具测试网络的状态及从网上获取…

java后端开发环境搭建 mac

在mac pro上搭建一套java 后端开发环境&#xff0c;主要安装的内容有&#xff1a;jdk、maven、git、tomcat、mysql、navicat、IntelliJ、redis。 本人mac pro的系统为mac OS Monterey 12.6.7&#xff0c;主机的硬件架构为x86_64。 左上角关于本机查看系统版本&#xff1b;终端…

LLM - Baichuan7B Lora 训练详解

目录 一.引言 二.环境准备 三.模型训练 1.依赖引入与 tokenizer 加载 2.加载 DataSet 与 Model 3.Model 参数配置 4.获取 peft Model 5.构造 Trainer 训练 6.训练完整代码 四.Shell 执行 1.脚本构建 2.训练流程 3.训练结果 五.总结 一.引言 LLM - Baichuan7B Tok…

Ubuntu18.04 docker kafka 本地测试环境搭建

文章目录 一、kafka 介绍二、Ubuntu docker kafka 本地测试环境搭建2.1 docker kafka 启动2.1.1 下载镜像2.1.2 启动 wurstmeister/zookeeper2.1.3 启动 wurstmeister/kafka 2.2 docker kafka 测试数据收发2.2.1 docker kafka 测试数据收发2.2.2 windows验证 三、嵌入式集成四、…