6.显示评论 + 添加评论

news2024/11/17 1:43:22

1.显示评论

  • 数据层:根据实体查询一页评论数据、根据实体查询评论的数量
  • 业务层:处理查询评论的业务、处理查询评论数量的业务
  • 表现层:显示帖子详情数据时,同时显示该帖子所有的评论数据

1.1 数据访问层

  • entity_type:实体类型(评论目标类别,例如 1 代表帖子、2 代表评论、3代表用户)
  • entity_id:类型目标(id 为 1、id为 2 的帖子)
  • target_id:指向某个评论的回复目标

创建表的实体类型,在 entity 包下创建 Comment 的实体类:

package com.example.demo.entity;

import java.util.Date;

public class Comment {

    private int id;
    private int userId;
    private int entityType;
    private int entityId;
    private int targetId;
    private String content;
    private int status;
    private Date createTime;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public int getEntityType() {
        return entityType;
    }

    public void setEntityType(int entityType) {
        this.entityType = entityType;
    }

    public int getEntityId() {
        return entityId;
    }

    public void setEntityId(int entityId) {
        this.entityId = entityId;
    }

    public int getTargetId() {
        return targetId;
    }

    public void setTargetId(int targetId) {
        this.targetId = targetId;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    @Override
    public String toString() {
        return "Comment{" +
                "id=" + id +
                ", userId=" + userId +
                ", entityType=" + entityType +
                ", entityId=" + entityId +
                ", targetId=" + targetId +
                ", content='" + content + '\'' +
                ", status=" + status +
                ", createTime=" + createTime +
                '}';
    }
}

开发实体组件:在 dao 包下新建一个接口 CommentMapper :

  •  查询评论需要支持分页查询,需要提供两个方法:查询某一页有多少个数据、一共有多少数据(知道总页数)
package com.example.demo.dao;

import com.example.demo.entity.Comment;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface CommentMapper {

    List<Comment> selectCommentsByEntity(int entityType, int entityId, int offset, int limit);

    int selectCountByEntity(int entityType, int entityId);

}

在 resources 资源文件下 mapper 包下创建 discusspost-mapper.xml 写实现方法 :

  • 定义查询字段
  • 实现上述两个方法的语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.dao.CommentMapper">

    <!--定义查询字段-->
    <sql id="selectFields">
        id, user_id, entity_type, entity_id, target_id, content, status, create_time
    </sql>

    <select id="selectCommentsByEntity" resultType="Comment">
        select <include refid="selectFields"></include>
        from comment
        where status = 0
        and entity_type = #{entityType}
        and entity_id = #{entityId}
        order by create_time asc
        limit #{offset}, #{limit}
    </select>

    <select id="selectCountByEntity" resultType="int">
        select count(id)
        from comment
        where status = 0
        and entity_type = #{entityType}
        and entity_id = #{entityId}
    </select>

</mapper>

1.2 业务层

在 service 包下新建业务组件 CommentService 类:

  • 注入 CommentMapper
  • 提供两个业务方法
  • 1.查询某一页数据,返回集合:实体类型、类型目标、分页、每一页数量
  • 2.一共有多少数据
package com.example.demo.service;

import com.example.demo.dao.CommentMapper;
import com.example.demo.entity.Comment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class CommentService {

    @Autowired
    private CommentMapper commentMapper;

    public List<Comment> findCommentsByEntity(int entityType, int entityId, int offset, int limit) {
        return commentMapper.selectCommentsByEntity(entityType, entityId, offset, limit);
    }

    public int findCommentCount(int entityType, int entityId) {
        return commentMapper.selectCountByEntity(entityType, entityId);
    }

}

1.3 表现层

在 controller 包下的 DiscussPostController 类( 查询帖子详情数据的方法)中 查询请求方法 补充:

  • 注入 CommentService
  • 查询不单是查询帖子数据,还要查询评论(支持分页,需要传入分页相关信息的 Page)
  • 补充评论分页信息:显示分页条数、显示路径、总的数据
  • 分页查询,调用 commentService,首先查询帖子数据(帖子实体类型、id、分页条件)得到一个集合(得到当前帖子的所有评论)
  • 将帖子实体类型写到 常量接口中(util 包下的 CommunityConstant 类中)
    /**
     * 实体类型: 帖子
     */
    int ENTITY_TYPE_POST = 1;

    /**
     * 实体类型: 评论
     */
    int ENTITY_TYPE_COMMENT = 2;
  • 此时 DiscussPostService 类中实现常量接口(implements CommunityConstant)

  • 补充帖子内容(将评论id、tardet_id 等信息转化为 User 对象得到 UserName,头像等内容):创建一个集合,对展示的数据进行统一封装
  • VoList——显示对象
  • 判断集合,如果集合非空,遍历集合,每次遍历得到一个评论,创建一个 Map,用来封装呈现给页面数据(也就是一个评论,将遍历的评论存入、将评论的作者存入),上述是关于帖子的评论
  • 但是评论也有评论,也就是回复:遍历的同时也要将 “回复列表” 查询到返回给页面(从评论中查找评论,目标是评论的评论)
  • 同理回复列表也需要创建一个集合对数据封装,然后对这个集合进行判断
  • 每次遍历得到一个回复,创建一个 Map,用来封装呈现给页面数据(也就是一个回复,将遍历的回复存入、将回复的作者存入) 
  • 评论是没有回复目标的,但是评论的评论也就是回复,才会有回复目标(给那个帖子回复),所以给回复添加回复目标
  • 最后将回复 Map 装入集合中
  • 跳到 “回复” 外的循环,将回复集合装入评论map中
  • 还要补充回复数量,存入评论中
  • 将评论装入评论集合中
  • 整个循环外,将最终结果放入 Model 中
    @Autowired
    private CommentService commentService;、

    //查询请求方法
    @RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET)
    public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model, Page page) {
        // 帖子
        DiscussPost post = discussPostService.findDiscussPostById(discussPostId);
        model.addAttribute("post", post);
        //第一种方法:在查询的时候使用关联查询 。优点:查询快;缺点:可能存在冗余、耦合
        //第二种方法:先查出帖子数据,根据 id 调用 Userservice 查询 User,再通过 Model 将 User 发送给 模板,
        // 这样模板得到了帖子,也得到了模板。优点:查询两次,没有冗余;缺点:查询慢
        //在这里使用第二种情况,查询慢可以使用 Redis 来优化
        // 作者
        User user = userService.findUserById(post.getUserId());
        // 把作者传给模板
        model.addAttribute("user", user);

        //评论分页信息
        page.setLimit(5);//每页5个评论
        page.setPath("discuss/detail/" + discussPostId);//访问路径
        page.setRows(post.getCommentCount());//总数

        // 评论: 给帖子的评论
        // 回复: 给评论的评论

        // 评论列表——发布帖子的评论列表
        //分页查询,调用 commentService,首先查询帖子数据(帖子实体类型、id、分页条件)得到一个集合(得到当前帖子的所有评论)
        List<Comment> commentList = commentService.findCommentsByEntity(
                ENTITY_TYPE_POST, post.getId(), page.getOffset(), page.getLimit());

        //评论VO列表——创建一个集合,对展示的数据进行统一封装
        List<Map<String, Object>> commentVoList = new ArrayList<>();

        //判断集合,如果集合非空,遍历集合,每次遍历得到一个评论
        if (commentList != null) {
            for (Comment comment : commentList) {
                // 评论VO:创建一个 Map,用来封装呈现给页面数据(也就是一个评论,将遍历的评论存入、将评论的作者存入)
                Map<String, Object> commentVo = new HashMap<>();
                // 评论存入
                commentVo.put("comment", comment);
                // 作者存入
                commentVo.put("user", userService.findUserById(comment.getUserId()));

                //但是评论也有评论,也就是回复:遍历的同时也要将 “回复列表” 查询到返回给页面(从评论中查找评论,目标是评论的评论)

                //回复列表
                List<Comment> replyList = commentService.findCommentsByEntity(
                        ENTITY_TYPE_COMMENT, comment.getId(),0, Integer.MAX_VALUE);
                //回复Vo列表:创建一个集合对数据封装
                List<Map<String, Object>> replyVoList = new ArrayList<>();

                //每次遍历得到一个回复,创建一个 Map,用来封装呈现给页面数据(也就是一个回复,将遍历的回复存入、将回复的作者存入)
                if (replyList != null) {
                    for (Comment reply: replyList) {
                        Map<String, Object> replyVo = new HashMap<>();
                        // 回复
                        replyVo.put("reply", reply);
                        // 作者
                        replyVo.put("user", userService.findUserById(reply.getUserId()));

                        //评论是没有回复目标的,但是评论的评论也就是回复,才会有回复目标(给那个帖子回复),所以给回复添加回复目标
                        // 回复目标
                        User target = reply.getTargetId() == 0 ? null : userService.findUserById(reply.getTargetId());
                        replyVo.put("target", target);

                        //最后将回复 Map 装入集合中
                        replyVoList.add(replyVo);
                    }
                }
                //将回复集合装入评论map中
                commentVo.put("replys", replyVoList);

                // 回复数量
                int replyCount = commentService.findCommentCount(ENTITY_TYPE_COMMENT, comment.getId());
                //存入评论中
                commentVo.put("replyCount", replyCount);

                //将评论装入评论集合中
                commentVoList.add(commentVo);
            }
        }
        //将最终结果放入 Model 中
        model.addAttribute("comments", commentVoList);

        return "/site/discuss-detail";
    }

2.添加评论

  • 数据层:增加评论数量、修改帖子的评论数量
  • 业务层:处理添加评论的业务、先增加评论、再更新帖子的评论数量
  • 表现层:处理添加评论数量的请求、设置添加评论的表单

2.1 数据层

在 dao 包下的 CommentMapper 中新增 添加评论 的方法:

    //添加评论
    int insertComment(Comment comment);

在 配置文件 comment-mapper.xml 中实现 sql:

  • 列出新增字段
  • 添加 insert 标签
    <!--添加评论查询字段-->
    <sql id="insertFields">
        user_id, entity_type, entity_id, target_id, content, status, create_time
    </sql>

    <!--添加评论sql-->
    <insert id="insertComment" parameterType="Comment">
        insert into comment(<include refid="insertFields"></include>)
        values(#{userId},#{entityType},#{entityId},#{targetId},#{content},#{status},#{createTime})
    </insert>

增加评论之后更新帖子数量,在 DiscussPostMapper.java 中新增方法

  • 根据 id 更新帖子数量
    //更新帖子数量
    int updateCommentCount(int id, int commentCount);

打开接口的配置文件 discusspost-mapper.xml 实现 sql: 

    <!--更新帖子数量-->
    <update id="updateCommentCount">
        update discuss_post set comment_count = #{commentCount} where id = #{id}
    </update>

2.2 业务层

在 service 包下的 DiscussPostService(帖子业务组件)中增加更新评论数量:

    //更新评论数量
    public int updateCommentCount(int id, int commentCount) {
        return discussPostMapper.updateCommentCount(id, commentCount);
    }

在 CommentService(显示评论的业务方法) 中处理增加评论业务:

  • 增加评论返回 int,参数为实体 Comment
  • 添加注解 @Transactional (声明隔离级别、传播机制):因为在增加评论方法中有两次 DMA 操作,进行事务管理,要么一起成功,要么一起失败
  • 增加评论的时候,需要过滤内容(标签、敏感词等),注入 SensitiveFilter(敏感词)
  • 调用 增加评论的方法
  • 在更新帖子评论数量:判断实体类型是否是帖子,实现 CommunityConstant 接口,在查找评论数量;最后更新到帖子表中(根据帖子 id更新),需要注入 DiscussPostService
    @Autowired
    private SensitiveFilter sensitiveFilter;

    @Autowired
    private DiscussPostService discussPostService;
    
    //增加评论的方法
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public int addComment(Comment comment) {
        if (comment == null) {
            throw new IllegalArgumentException("参数不能为空");
        }
        //添加评论:过滤标签和敏感词
        comment.setContent(HtmlUtils.htmlEscape(comment.getContent()));
        comment.setContent(sensitiveFilter.filter(comment.getContent()));
        int rows = commentMapper.insertComment(comment);

        //更新帖子评论数量
        //判断实体类型是否是帖子,实现 CommunityConstant 接口,在查找评论数量;
        //最后更新到帖子表中(根据帖子 id更新),需要注入 DiscussPostService
        if (comment.getEntityType() == ENTITY_TYPE_POST) {
            int count = commentMapper.selectCountByEntity(comment.getEntityType(), comment.getEntityId());
            discussPostService.updateCommentCount(comment.getEntityId(), count);
        }
        return rows;
    }

2.3 表现层

在 controller 包下新建 CommentController (处理增加评论的请求)类

  • 声明 controller 访问路径
  • 增加请求路径(添加帖子 id 路径),增加是POST 请求
  • 通过 @PathVariable 得到帖子 id 参数,(传入提交内容、id、评论类型,声明实体类 Comment)
  • 注入 CommentService,HostHolder(增加评论为当前用户增加);
  • 补充实体类:UserId、状态、当前时间
  • 添加评论
  • 最终重定向帖子详情页
package com.example.demo.controller;

import com.example.demo.entity.Comment;
import com.example.demo.service.CommentService;
import com.example.demo.util.HostHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.Date;

/**
 * 处理增加评论的请求
 */
@Controller
@RequestMapping("/comment")
public class CommentController {

    @Autowired
    private CommentService commentService;

    @Autowired
    private HostHolder hostHolder;

    @RequestMapping(path = "/add/{discussPostId}", method = RequestMethod.POST)
    //通过 @PathVariable 得到帖子 id 参数,(传入提交内容、id、评论类型,声明实体类 Comment)
    public String addComment(@PathVariable("discussPostId") int discussPostId, Comment comment) {
        comment.setUserId(hostHolder.getUser().getId());
        comment.setStatus(0);
        comment.setCreateTime(new Date());
        commentService.addComment(comment);

        return "redirect:/discuss/detail/" + discussPostId;
    }
}

前端页面 discuss-detail.html 中的回帖:

<!-- 回帖 -->
			<div class="container mt-3">
				<!-- 回帖数量 -->
				<div class="row">
					<div class="col-8">
						<h6><b class="square"></b> <i th:text="${post.commentCount}">30</i>条回帖</h6>
					</div>
					<div class="col-4 text-right">
						<a href="#replyform" class="btn btn-primary btn-sm">&nbsp;&nbsp;回&nbsp;&nbsp;帖&nbsp;&nbsp;</a>
					</div>
				</div>
				<!-- 回帖列表 -->
				<ul class="list-unstyled mt-4">
					<li class="media pb-3 pt-3 mb-3 border-bottom" th:each="cvo:${comments}">
						<a href="profile.html">
							<img th:src="${cvo.user.headerUrl}" class="align-self-start mr-4 rounded-circle user-header" alt="用户头像" >
						</a>
						<div class="media-body">
							<div class="mt-0">
								<span class="font-size-12 text-success" th:utext="${cvo.user.username}">掉脑袋切切</span>
								<span class="badge badge-secondary float-right floor">
									<i th:text="${page.offset + cvoStat.count}">1</i>#
								</span>
							</div>
							<div class="mt-2" th:utext="${cvo.comment.content}">
								这开课时间是不是有点晚啊。。。
							</div>
							<div class="mt-4 text-muted font-size-12">
								<span>发布于 <b th:text="${#dates.format(cvo.comment.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</b></span>
								<ul class="d-inline float-right">
									<li class="d-inline ml-2"><a href="#" class="text-primary">赞(1)</a></li>
									<li class="d-inline ml-2">|</li>
									<li class="d-inline ml-2"><a href="#" class="text-primary">回复(<i th:text="${cvo.replyCount}">2</i>)</a></li>
								</ul>
							</div>
							<!-- 回复列表 -->
							<ul class="list-unstyled mt-4 bg-gray p-3 font-size-12 text-muted">

								<li class="pb-3 pt-3 mb-3 border-bottom" th:each="rvo:${cvo.replys}">
									<div>
										<span th:if="${rvo.target==null}">
											<b class="text-info" th:text="${rvo.user.username}">寒江雪</b>:&nbsp;&nbsp;
										</span>
										<span th:if="${rvo.target!=null}">
											<i class="text-info" th:text="${rvo.user.username}">Sissi</i> 回复
											<b class="text-info" th:text="${rvo.target.username}">寒江雪</b>:&nbsp;&nbsp;
										</span>
										<span th:utext="${rvo.reply.content}">这个是直播时间哈,觉得晚的话可以直接看之前的完整录播的~</span>
									</div>
									<div class="mt-3">
										<span th:text="${#dates.format(rvo.reply.createTime,'yyyy-MM-dd HH:mm:ss')}">2019-04-15 15:32:18</span>
										<ul class="d-inline float-right">
											<li class="d-inline ml-2"><a href="#" class="text-primary">赞(1)</a></li>
											<li class="d-inline ml-2">|</li>
											<li class="d-inline ml-2"><a th:href="|#huifu-${rvoStat.count}|" data-toggle="collapse" class="text-primary">回复</a></li>
										</ul>
										<div th:id="|huifu-${rvoStat.count}|" class="mt-4 collapse">
											<form method="post" th:action="@{|/comment/add/${post.id}|}">
												<div>
													<input type="text" class="input-size" name="content" th:placeholder="|回复${rvo.user.username}|"/>
													<input type="hidden" name="entityType" value="2">
													<input type="hidden" name="entityId" th:value="${cvo.comment.id}">
													<input type="hidden" name="targetId" th:value="${rvo.user.id}">
												</div>
												<div class="text-right mt-2">
													<button type="submit" class="btn btn-primary btn-sm" onclick="#">&nbsp;&nbsp;回&nbsp;&nbsp;复&nbsp;&nbsp;</button>
												</div>
											</form>
										</div>
									</div>								
								</li>

								<!-- 回复输入框 -->
								<li class="pb-3 pt-3">
									<form method="post" th:action="@{|/comment/add/${post.id}|}">
										<div>
											<input type="text" class="input-size" name="content" placeholder="请输入你的观点"/>
											<input type="hidden" name="entityType" value="2">
											<input type="hidden" name="entityId" th:value="${cvo.comment.id}">
										</div>
										<div class="text-right mt-2">
											<button type="submit" class="btn btn-primary btn-sm" onclick="#">&nbsp;&nbsp;回&nbsp;&nbsp;复&nbsp;&nbsp;</button>
										</div>
									</form>
								</li>
							</ul>
						</div>
					</li>
				</ul>
				<!-- 分页 -->
				<nav class="mt-5" th:replace="index::pagination">
					<ul class="pagination justify-content-center">
						<li class="page-item"><a class="page-link" href="#">首页</a></li>
						<li class="page-item disabled"><a class="page-link" href="#">上一页</a></li>
						<li class="page-item active"><a class="page-link" href="#">1</a></li>
						<li class="page-item"><a class="page-link" href="#">2</a></li>
						<li class="page-item"><a class="page-link" href="#">3</a></li>
						<li class="page-item"><a class="page-link" href="#">4</a></li>
						<li class="page-item"><a class="page-link" href="#">5</a></li>
						<li class="page-item"><a class="page-link" href="#">下一页</a></li>
						<li class="page-item"><a class="page-link" href="#">末页</a></li>
					</ul>
				</nav>			
			</div>
			<!-- 回帖输入 -->
			<div class="container mt-3">
				<form class="replyform" method="post" th:action="@{|/comment/add/${post.id}|}">
					<p class="mt-3">
						<a name="replyform"></a>
						<textarea placeholder="在这里畅所欲言你的看法吧!" name="content"></textarea>
						<input type="hidden" name="entityType" value="1">
						<input type="hidden" name="entityId" th:value="${post.id}">
					</p>
					<p class="text-right">
						<button type="submit" class="btn btn-primary btn-sm">&nbsp;&nbsp;回&nbsp;&nbsp;帖&nbsp;&nbsp;</button>
					</p>
				</form>
			</div>
		</div>

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

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

相关文章

小红书达人等级有哪些,不同粉丝量有什么区别?

小红书的种草能力和社区加电商的模式&#xff0c;使得越来越多品牌将目光放在小红书笔记上。而在平台的营销与传播&#xff0c;多是借助达人进行的&#xff0c;今天为大家分享下小红书达人等级有哪些&#xff0c;不同粉丝量有什么区别&#xff1f; 一、小红书达人等级划分 虽然…

医院手术麻醉信息系统全套源码,自主版权,支持二次开发

医院手术麻醉信息系统全套商业源码&#xff0c;自主版权&#xff0c;支持二次开发 手术麻醉信息系统是HIS产品的中的一个组成部分&#xff0c;主要应用于医院的麻醉科&#xff0c;属于电子病历类产品。医院麻醉监护的功能覆盖整个手术与麻醉的全过程&#xff0c;包括手术申请与…

uniapp实现多时间段设置

功能说明&#xff1a; 1 点击新增时间&#xff0c;出现一个默认时间段模板&#xff0c;不能提交 2 点击“新增时间文本”&#xff0c;弹出弹窗&#xff0c;选择时间&#xff0c;不允许开始时间和结束时间同时为00:00&#xff0c; <view class"item_cont"> …

JWT 还能这样的去理解嘛??

其他系列文章目录 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章目录 文章目录 一、什么是 JWT? 二、JWT 由哪些部分组成&#xff1f; 2.1Header 2.2Payload 2.3Signature 三、如何基于 JWT 进行身份验证&#xff1f; 四、如何防止 JWT 被篡改&a…

_STORAGE_WRITE_ERROR_ thinkphp报错问题原因

整个报错内容如下 Uncaught exception Think\Exception with message _STORAGE_WRITE_ERROR_:./Runtime/Cache/Home/1338db9dec777aab181d4e74d1bdf964.php in C:\inetpub\wwwroot\ThinkPHP\Common\functions.php:101 Stack trace: #0 C:\inetpub\wwwroot\ThinkPHP\Library\…

“圆柱-计算公式“技术支持网址

该软件可以计算圆柱的底面圆周长、底面积、侧面积和体积。 您在使用中有遇到任何问题都可以和我们联系。我们会在第一时间回复您。 邮箱地址&#xff1a;elmo30zeongmail.com 谢谢&#xff01;

【深度学习】CNN中pooling层的作用

1、pooling是在卷积网络&#xff08;CNN&#xff09;中一般在卷积层&#xff08;conv&#xff09;之后使用的特征提取层&#xff0c;使用pooling技术将卷积层后得到的小邻域内的特征点整合得到新的特征。一方面防止无用参数增加时间复杂度&#xff0c;一方面增加了特征的整合度…

骨传导能保护听力吗?为什么说骨传导耳机可以保护听力?

由于骨传导耳机的特殊传声方式&#xff0c;是可以保护听力的。 首先了解下骨传导耳机的传声方式是什么&#xff1a; 骨传导耳机是通过骨骼震动传导技术&#xff0c;将声音传至颅骨&#xff0c;然后通过颅骨传导到内耳&#xff0c;直接刺激听觉神经&#xff0c;使人感知到声音…

最全的电商API接口|全面淘宝平台数据接口参数和文档说明

淘宝联盟“工具服务商”开放招募 为了支持生态淘宝客业务提效及新业务模式拓展&#xff0c;淘宝联盟针对各工具业务模式招募若干工具服务商团队&#xff0c;仅限符合该招募规则的开发者申请创建工具服务商AppKey&#xff0c;并针对新引入的工具服务商将开放对应模式所需要的“服…

易点易动固定资产管理系统:全生命周期管理的理想选择

在现代企业中&#xff0c;固定资产管理是一项至关重要的任务。为了确保企业的资产安全、提高资产利用率&#xff0c;全面管理固定资产的生命周期至关重要。易点易动固定资产管理系统为企业提供了一种全面的解决方案&#xff0c;实现了从固定资产申购、采购、入库、领用、退库、…

iOS强引用引起的内存泄漏

项目中遇到一个问题&#xff1a; 1.在A页面的ViewDidLoad 方法里写了一个接收通知的方法&#xff0c;如下图&#xff1a; 然后在B页面发送通知 &#xff08;注&#xff1a;下图的NOTI 是 [NSNotificationCenter defaultCenter] 的宏&#xff0c; 考虑一下可能有小白看这篇文章…

打印菱形-第11届蓝桥杯选拔赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第9讲。 打印菱形&#xff…

Android笔记(十五):JetPack Compose的附带效应(二)-produceState和derivedStateOf

在本笔记中&#xff0c;将结合实例介绍produceState和derivedStateOf两个可组合函数。它们分别实现状态的转换。 &#xff08;1&#xff09;produceState将非Compose状态转换虫Compose状态 &#xff08;2&#xff09;derivedStateOf将多个状态转换成其他状态。 一、produceSta…

2023年金融信创行业研究报告

第一章 行业概况 1.1 定义 金融信创是指在金融行业中应用的信息技术&#xff0c;特别是那些涉及到金融IT基础设施、基础软件、应用软件和信息安全等方面的技术和产品。这一概念源于更广泛的“信创 (信息技术应用创新)”&#xff0c;即通过中国国产信息技术替换海外信息技术&a…

全球最大生产基地已投产,百年京西借智能悬架谋「新生」

受相关等爆款车型的高配置率及销量带动&#xff0c;空气悬架市场热度不减。 比如&#xff0c;理想在今年的理想魔毯空气悬架技术日上宣布&#xff0c;搭载空气悬架的车型累计交付已突破20万辆&#xff0c;在所有已交付的L9、L8、L7中&#xff0c;配备空气悬架的比例达93%。 作…

php通过curl方式发送接受xml数据

目录 1、php通过curl方式发送xml数据 2、php通过file_get_contents接受curl方式发送xml数据 1、php通过curl方式发送xml数据 <?php function sendXmlData($url, $xmlData) {$ch curl_init();curl_setopt($ch, CURLOPT_URL, $url);curl_setopt($ch, CURLOPT_RETURNTRANSFE…

亚马逊云科技向量数据库助力生成式AI成功落地实践探秘(二)

向量数据库选择哪种近似搜索算法&#xff0c;选择合适的集群规模以及集群设置调优对于知识库的读写性能也十分关键&#xff0c;主要需要考虑以下几个方面&#xff1a; 向量数据库算法选择 在 OpenSearch 里&#xff0c;提供了两种 k-NN 的算法&#xff1a;HNSW (Hierarchical…

代码随想录算法训练营第四十四天【动态规划part06】 | 完全背包、518. 零钱兑换 II、377. 组合总和 Ⅳ

完全背包 有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 题目链接&#xff1a; 题目页…

android keylayout键值适配

1、通过getevent打印查看当前keyevent数字对应事件和物理码 2、dumpsys input 查看输入事件对应的 KeyLayoutFile: /system/usr/keylayout/Vendor_6080_Product_8060.kl 3、通过物理码修改键值映射&#xff0c;修改/system/usr/keylayout/目录下的文件

嵌入式系统在工业自动化中的智能化和自适应控制

嵌入式系统在工业自动化中扮演着实现智能化和自适应控制的重要角色。通过集成先进的算法和人工智能技术&#xff0c;嵌入式系统能够实现对生产过程的智能监控、分析、决策和调整&#xff0c;以提高生产线的效率、质量和稳定性。下面将详细介绍嵌入式系统在工业自动化中智能化和…