本文介绍 SpringBoot + Spring Data JPA + Thymeleaf 实现关注取消关注互相关注的功能。采用 Bootstrap + ajax 显示数据,样式是模仿慕课网,获取样式,点此直达。
本项目也使用了Spring Data JPA 分页功能,因为数据比较少,所以设置一页显示一个。
动态效果图如下,点击放大
user 表主要是有一个 id 主键, fan_size 粉丝数,follow_size 关注数 ;
relationship 表有两个字段 from_user_id,to_user_id ,组成联合主键。
本文使用的是是 Spring Data JPA,无需设计数据表,直接通过实体生成。
User.java
其他与本文无关的字段,这里省掉了。
Relationship.java
RelationshipPK.java
UserRepository.java
RelationshipRepository.java
RelationshipService.java
RelationshipServiceImpl.java
UserSpaceController.java
HTML
JS
CSS
本文地址:https://liuyanzhao.com/8077.html
                    本项目也使用了Spring Data JPA 分页功能,因为数据比较少,所以设置一页显示一个。
动态效果图如下,点击放大
一、数据库设计
user 表主要是有一个 id 主键, fan_size 粉丝数,follow_size 关注数 ;
relationship 表有两个字段 from_user_id,to_user_id ,组成联合主键。
本文使用的是是 Spring Data JPA,无需设计数据表,直接通过实体生成。
二、实体
User.java
- package com.liuyanzhao.forum.entity;
 - import lombok.Data;
 - import javax.persistence.*;
 - import javax.validation.constraints.NotEmpty;
 - import javax.validation.constraints.Size;
 - import java.io.Serializable;
 - /**
 - * @author 言曌
 - * @date 2018/3/19 下午9:54
 - */
 - @Entity
 - @Data
 - public class User implements Serializable {
 - private static final long serialVersionUID = 6147345506206285446L;
 - @Id // 主键
 - @GeneratedValue(strategy = GenerationType.IDENTITY) // 自增长策略
 - private Integer id; // 用户的唯一标识
 - @NotEmpty(message = "昵称不能为空")
 - @Size(min = 2, max = 12, message = "昵称长度必须为2-12个字符")
 - @Column(nullable = false, length = 12)
 - private String nickname;
 - @NotEmpty(message = "用户名不能为空")
 - @Size(min = 4, max = 20, message = "用户名长度必须为4-20个字符")
 - @Column(nullable = false, length = 20, unique = true)
 - private String username; // 用户账号,用户登录时的唯一标识
 - @NotEmpty(message = "密码不能为空")
 - @Size(max = 100, message = "密码长度最多100个字符")
 - @Column(length = 100)
 - private String password; // 登录时密码
 - @Column(length = 200)
 - @Size(max = 200, message = "头像链接长度最多200个字符")
 - private String avatar; // 头像图片地址
 - private Integer followSize = 0;//关注数
 - private Integer fanSize = 0; //粉丝数
 - @Transient
 - private Integer isFriend = 0;//关系,0表示没有关系,2表示互相关注
 - public User() {
 - }
 - }
 
其他与本文无关的字段,这里省掉了。
Relationship.java
- package com.liuyanzhao.forum.entity;
 - import javax.persistence.Column;
 - import javax.persistence.Entity;
 - import javax.persistence.Id;
 - import javax.persistence.IdClass;
 - /**
 - * @author 言曌
 - * @date 2018/4/24 下午9:38
 - */
 - @Entity
 - @IdClass(RelationshipPK.class)
 - public class Relationship {
 - private Integer fromUserId;
 - private Integer toUserId;
 - public Relationship() {
 - }
 - public Relationship(Integer fromUserId, Integer toUserId) {
 - this.fromUserId = fromUserId;
 - this.toUserId = toUserId;
 - }
 - @Id
 - @Column(name = "from_user_id", nullable = false)
 - public Integer getFromUserId() {
 - return fromUserId;
 - }
 - public void setFromUserId(Integer fromUserId) {
 - this.fromUserId = fromUserId;
 - }
 - @Id
 - @Column(name = "to_user_id", nullable = false)
 - public Integer getToUserId() {
 - return toUserId;
 - }
 - public void setToUserId(Integer toUserId) {
 - this.toUserId = toUserId;
 - }
 - @Override
 - public boolean equals(Object o) {
 - if (this == o) return true;
 - if (o == null || getClass() != o.getClass()) return false;
 - Relationship that = (Relationship) o;
 - if (fromUserId != null ? !fromUserId.equals(that.fromUserId) : that.fromUserId != null) return false;
 - if (toUserId != null ? !toUserId.equals(that.toUserId) : that.toUserId != null) return false;
 - return true;
 - }
 - @Override
 - public int hashCode() {
 - int result = fromUserId != null ? fromUserId.hashCode() : 0;
 - result = 31 * result + (toUserId != null ? toUserId.hashCode() : 0);
 - return result;
 - }
 - }
 
RelationshipPK.java
- package com.liuyanzhao.forum.entity;
 - import javax.persistence.Column;
 - import javax.persistence.Id;
 - import java.io.Serializable;
 - /**
 - * @author 言曌
 - * @date 2018/4/24 下午9:38
 - */
 - public class RelationshipPK implements Serializable {
 - private Integer fromUserId;
 - private Integer toUserId;
 - @Column(name = "from_user_id", nullable = false)
 - @Id
 - public Integer getFromUserId() {
 - return fromUserId;
 - }
 - public void setFromUserId(Integer fromUserId) {
 - this.fromUserId = fromUserId;
 - }
 - @Column(name = "to_user_id", nullable = false)
 - @Id
 - public Integer getToUserId() {
 - return toUserId;
 - }
 - public void setToUserId(Integer toUserId) {
 - this.toUserId = toUserId;
 - }
 - @Override
 - public boolean equals(Object o) {
 - if (this == o) return true;
 - if (o == null || getClass() != o.getClass()) return false;
 - RelationshipPK that = (RelationshipPK) o;
 - if (fromUserId != null ? !fromUserId.equals(that.fromUserId) : that.fromUserId != null) return false;
 - if (toUserId != null ? !toUserId.equals(that.toUserId) : that.toUserId != null) return false;
 - return true;
 - }
 - @Override
 - public int hashCode() {
 - int result = fromUserId != null ? fromUserId.hashCode() : 0;
 - result = 31 * result + (toUserId != null ? toUserId.hashCode() : 0);
 - return result;
 - }
 - }
 
三、Dao 层
UserRepository.java
- package com.liuyanzhao.forum.repository;
 - import com.liuyanzhao.forum.entity.User;
 - import org.springframework.data.domain.Page;
 - import org.springframework.data.domain.Pageable;
 - import org.springframework.data.jpa.repository.JpaRepository;
 - import org.springframework.data.jpa.repository.Query;
 - import java.util.Collection;
 - import java.util.List;
 - /**
 - * @author 言曌
 - * @date 2018/3/20 下午5:26
 - */
 - public interface UserRepository extends JpaRepository<User, Integer> {
 - /**
 - * 根据id集合查询用户,分页查询
 - *
 - * @param ids
 - * @return
 - */
 - Page<User> findByIdIn(List<Integer> ids, Pageable pageable);
 - /**
 - * 根据id集合查询用户,不分页
 - *
 - * @param ids
 - * @return
 - */
 - List<User> findByIdIn(List<Integer> ids);
 - }
 
RelationshipRepository.java
- package com.liuyanzhao.forum.repository;
 - import com.liuyanzhao.forum.entity.Relationship;
 - import com.liuyanzhao.forum.entity.RelationshipPK;
 - import org.springframework.data.jpa.repository.JpaRepository;
 - import org.springframework.data.jpa.repository.Query;
 - import org.springframework.data.repository.query.Param;
 - import java.util.List;
 - /**
 - * @author 言曌
 - * @date 2018/4/24 下午9:47
 - */
 - public interface RelationshipRepository extends JpaRepository<Relationship, RelationshipPK> {
 - /**
 - * 根据关注者id查找所有记录(查找关注的人的id)
 - *
 - * @param fromUserId
 - * @return
 - */
 - @Query("select toUserId from Relationship where fromUserId =:fromUserId")
 - List<Integer> findByFromUserId(@Param("fromUserId") Integer fromUserId);
 - /**
 - * 根据被关注者查找所有记录(查找粉丝的id)
 - *
 - * @param toUserId
 - * @return
 - */
 - @Query("select fromUserId from Relationship where toUserId =:toUserId")
 - List<Integer> findByToUserId(@Param("toUserId") Integer toUserId);
 - /**
 - * 查询该用户的互相关注id
 - * @param userId
 - * @return
 - */
 - @Query(value = "SELECT DISTINCT t1.from_user_id FROM (SELECT * FROM relationship WHERE to_user_id = ?1) AS t1 INNER JOIN relationship t2 ON t1.from_user_id = t2.to_user_id", nativeQuery = true)
 - List<Integer> findFriendsByUserId(Integer userId);
 - /**
 - * 查询关注数
 - * @param fromUserId
 - * @return
 - */
 - Integer countByFromUserId(Integer fromUserId);
 - /**
 - * 查询粉丝数
 - * @param toUserId
 - * @return
 - */
 - Integer countByToUserId(Integer toUserId);
 - }
 
四、Service 层
RelationshipService.java
- package com.liuyanzhao.forum.service;
 - import com.liuyanzhao.forum.entity.Relationship;
 - import com.liuyanzhao.forum.entity.User;
 - import org.springframework.data.domain.Page;
 - import org.springframework.data.domain.Pageable;
 - import java.util.List;
 - /**
 - * @author 言曌
 - * @date 2018/4/24 下午10:10
 - */
 - public interface RelationshipService {
 - /**
 - * 列出所有的关注者
 - *
 - * @return
 - */
 - Page<User> listFollows(Integer userId, Pageable pageable);
 - /**
 - * 列出所有的粉丝
 - *
 - * @return
 - */
 - Page<User> listFans(Integer userId, Pageable pageable);
 - /**
 - * 列出互相关注的id
 - *
 - * @param userId
 - * @return
 - */
 - List<Integer> listFriends(Integer userId);
 - /**
 - * 添加关系
 - *
 - * @param relationship
 - */
 - void saveRelationship(Relationship relationship);
 - /**
 - * 去除关系
 - *
 - * @param relationship
 - */
 - void removeRelationship(Relationship relationship);
 - /**
 - * 更新关注数
 - */
 - void updateFollowSize(Integer userId);
 - /**
 - * 更新粉丝数
 - */
 - void updateFanSize(Integer userId);
 - }
 
RelationshipServiceImpl.java
- package com.liuyanzhao.forum.service.impl;
 - import com.liuyanzhao.forum.entity.Relationship;
 - import com.liuyanzhao.forum.entity.User;
 - import com.liuyanzhao.forum.repository.RelationshipRepository;
 - import com.liuyanzhao.forum.repository.UserRepository;
 - import com.liuyanzhao.forum.service.RelationshipService;
 - import org.springframework.beans.factory.annotation.Autowired;
 - import org.springframework.data.domain.Page;
 - import org.springframework.data.domain.Pageable;
 - import org.springframework.stereotype.Service;
 - import java.util.List;
 - /**
 - * @author 言曌
 - * @date 2018/4/24 下午10:23
 - */
 - @Service
 - public class RelationshipServiceImpl implements RelationshipService {
 - @Autowired
 - private RelationshipRepository relationshipRepository;
 - @Autowired
 - private UserRepository userRepository;
 - @Override
 - public Page<User> listFollows(Integer userId, Pageable pageable) {
 - List<Integer> relationshipList = relationshipRepository.findByFromUserId(userId);
 - Page<User> userPage = userRepository.findByIdIn(relationshipList, pageable);
 - return userPage;
 - }
 - @Override
 - public Page<User> listFans(Integer userId, Pageable pageable) {
 - List<Integer> relationshipList = relationshipRepository.findByToUserId(userId);
 - Page<User> userPage = userRepository.findByIdIn(relationshipList, pageable);
 - return userPage;
 - }
 - @Override
 - public List<Integer> listFriends(Integer userId) {
 - List<Integer> relationshipList = relationshipRepository.findFriendsByUserId(userId);
 - // List<User> userList = userRepository.findByIdIn(relationshipList);
 - return relationshipList;
 - }
 - @Override
 - public void saveRelationship(Relationship relationship) {
 - //添加关注
 - relationshipRepository.save(relationship);
 - //更新双方关注数和粉丝数
 - updateFollowSize(relationship.getFromUserId());
 - updateFanSize(relationship.getToUserId());
 - }
 - @Override
 - public void removeRelationship(Relationship relationship) {
 - //删除关系
 - relationshipRepository.delete(relationship);
 - //更新双方关注数和粉丝数
 - updateFollowSize(relationship.getFromUserId());
 - updateFanSize(relationship.getToUserId());
 - }
 - @Override
 - public void updateFollowSize(Integer userId) {
 - User user = userRepository.findById(userId).get();
 - user.setFollowSize(relationshipRepository.countByFromUserId(userId));
 - userRepository.save(user);
 - }
 - @Override
 - public void updateFanSize(Integer userId) {
 - User user = userRepository.findById(userId).get();
 - user.setFanSize(relationshipRepository.countByToUserId(userId));
 - userRepository.save(user);
 - }
 - }
 
五、Controller 层
UserSpaceController.java
- package com.liuyanzhao.forum.controller;
 - import com.liuyanzhao.forum.controller.common.BaseController;
 - import com.liuyanzhao.forum.entity.*;
 - import com.liuyanzhao.forum.repository.UserRepository;
 - import com.liuyanzhao.forum.service.*;
 - import com.liuyanzhao.forum.vo.Response;
 - import org.springframework.beans.factory.annotation.Autowired;
 - import org.springframework.data.domain.Page;
 - import org.springframework.data.domain.PageRequest;
 - import org.springframework.http.ResponseEntity;
 - import org.springframework.security.access.prepost.PreAuthorize;
 - import org.springframework.security.core.context.SecurityContextHolder;
 - import org.springframework.stereotype.Controller;
 - import org.springframework.ui.Model;
 - import org.springframework.web.bind.annotation.*;
 - import org.springframework.web.servlet.ModelAndView;
 - import java.util.List;
 - /**
 - * @author 言曌
 - * @date 2018/4/24 下午1:15
 - */
 - @RequestMapping("/manage")
 - @Controller
 - @PreAuthorize("hasAnyAuthority('ROLE_ADMIN','ROLE_USER')") // 指定角色权限才能操作方法
 - public class UserSpaceController extends BaseController {
 - @Autowired
 - private RelationshipService relationshipService;
 - @Autowired
 - private UserRepository userRepository;
 - @GetMapping("/relationships")
 - public String relationships() {
 - return "forward:/manage/relationships/follows";
 - }
 - //粉丝-关注 start
 - /**
 - * 我的关注者列表
 - * @param userId
 - * @param optType
 - * @return
 - */
 - @GetMapping("/relationships/follows")
 - public ModelAndView follows(
 - @RequestParam(value = "async", required = false) boolean async,
 - @RequestParam(value = "page", defaultValue = "1", required = false) Integer page,
 - @RequestParam(value = "size", defaultValue = "1", required = false) Integer size,
 - Model model) {
 - Long startTime = System.currentTimeMillis();
 - User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
 - PageRequest pageRequest = new PageRequest(page - 1, size);
 - Page<User> userPage = relationshipService.listFollows(user.getId(), pageRequest);
 - List<Integer> friendIds = relationshipService.listFriends(user.getId());
 - List<User> userList = userPage.getContent();
 - for (int i = 0; i < userList.size(); i++) {
 - if (friendIds.contains(userList.get(i).getId())) {
 - userPage.getContent().get(i).setIsFriend(2);
 - }
 - }
 - model.addAttribute("userPage", userPage);
 - Long endTime = System.currentTimeMillis();
 - System.out.println("耗时" + (endTime - startTime) + "ms");
 - model.addAttribute("is_follows", true);
 - return new ModelAndView(async == true ? "home/userspace/relationship :: .tab-pane" : "home/userspace/relationship");
 - }
 - /**
 - * 我的粉丝列表
 - * @param userId
 - * @param optType
 - * @return
 - */
 - @GetMapping("/relationships/fans")
 - public ModelAndView fans(
 - @RequestParam(value = "async", required = false) boolean async,
 - @RequestParam(value = "page", defaultValue = "1", required = false) Integer page,
 - @RequestParam(value = "size", defaultValue = "1", required = false) Integer size,
 - Model model) {
 - Long startTime = System.currentTimeMillis();
 - User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
 - PageRequest pageRequest = new PageRequest(page - 1, size);
 - Page<User> userPage = relationshipService.listFans(user.getId(), pageRequest);
 - List<Integer> friendIds = relationshipService.listFriends(user.getId());
 - List<User> userList = userPage.getContent();
 - for (int i = 0; i < userList.size(); i++) {
 - if (friendIds.contains(userList.get(i).getId())) {
 - userPage.getContent().get(i).setIsFriend(2);
 - }
 - }
 - model.addAttribute("userPage", userPage);
 - Long endTime = System.currentTimeMillis();
 - System.out.println("耗时" + (endTime - startTime) + "ms");
 - model.addAttribute("is_fans", "true");
 - return new ModelAndView(async == true ? "home/userspace/relationship :: .tab-pane" : "home/userspace/relationship");
 - }
 - /**
 - * 添加关系
 - * @param userId
 - * @param optType
 - * @return
 - */
 - @PostMapping("/relationships")
 - public ResponseEntity<Response> followUser(Integer userId, String optType) {
 - User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
 - //1、判断用户是否存在
 - User temp = userRepository.findById(userId).get();
 - if (temp == null) {
 - return ResponseEntity.ok().body(new Response(false, "用户不存在"));
 - }
 - //2、判断是关注还是取消关注
 - //关注
 - if ("follow".equals(optType)) {
 - relationshipService.saveRelationship(new Relationship(user.getId(), userId));
 - } else if ("notfollow".equals(optType)) {
 - //取消关注
 - relationshipService.removeRelationship(new Relationship(user.getId(), userId));
 - } else {
 - //非法操作
 - return ResponseEntity.ok().body(new Response(false, "非法操作"));
 - }
 - Integer fanSize = userRepository.findById(userId).get().getFanSize();
 - return ResponseEntity.ok().body(new Response(true, "操作成功",fanSize));
 - }
 - //粉丝-关注 end
 - }
 
七、视图层
HTML
- <div class="box">
 - <div class="box-header with-border">
 - <h3 class="box-title">关系管理</h3>
 - </div>
 - <div class="box-body" id="right-box-body">
 - <div id="right-box-body-replace">
 - <div class="nav-tabs-custom" style="box-shadow: 0 0;">
 - <ul class="nav nav-tabs">
 - <li th:class="${is_follows}?active:''">
 - <a href="javascript:void(0)" data-toggle="tab"
 - class="relationship-tab-btn"
 - data-th-attr="data-type=follows">我的关注</a>
 - </li>
 - <li th:class="${is_fans}?active:''">
 - <a href="javascript:void(0)" data-toggle="tab"
 - class="relationship-tab-btn" data-th-attr="data-type=fans">我的粉丝</a>
 - </li>
 - </ul>
 - <div class="tab-content">
 - <div class="tab-pane active">
 - <div class="concern-list" th:if="${userPage.totalElements != 0}">
 - <ul>
 - <li class="box" th:each="user : ${userPage.content}">
 - <div class="left-img">
 - <a href="/u/3078817" target="_blank">
 - <img th:src="${user.avatar}"
 - class="top_head">
 - </a>
 - </div>
 - <div class="right-c">
 - <div class="title">
 - <a th:href="@{'/u/'+${user.username}}" target="_blank">
 - <span class="nickname"
 - th:text="${user.nickname}">言曌</span>
 - </a>
 - </div>
 - <p class="desc" title="全栈工程师"
 - th:text="${user.job.name}">全栈工程师</p>
 - <div class="fs-line">
 - <a href="/u/3078817/follows" class="u-target">
 - <span class="group">
 - <em>关注</em>
 - <em class="u-margin-l-5 follow-size" th:text="${user.followSize}">3</em>
 - </span>
 - </a>
 - <a href="/u/3078817/fans"
 - class="u-target u-margin-l-15">
 - <span class="group">
 - <em>粉丝</em>
 - <em class="u-margin-l-5 fan-size" th:text="${user.fanSize}">61</em>
 - </span>
 - </a>
 - </div>
 - <div class="btn-line" th:if="${is_follows}">
 - <a href="javascript:void(0)"
 - data-th-attr="data-uid=${user.id},opt-type=follow"
 - class="btn-o btn-green-o js-concern-follow"
 - style="display: none;">关注</a>
 - <a href="javascript:void(0)"
 - data-th-attr="data-uid=${user.id},opt-type=notfollow"
 - class="btn-o btn-gray-o js-concern-already"
 - th:if="${user.isFriend!=2}">已关注</a>
 - <a href="javascript:void(0)"
 - data-th-attr="data-uid=${user.id},opt-type=notfollow"
 - class="btn-o btn-gray-o js-concern-mutual"
 - th:if="${user.isFriend==2}">互相关注</a>
 - <a href="/u/2478917/messages?uid=3078817"
 - target="_blank"
 - class="btn-o btn-gray-o js-concern-msg">私信</a>
 - </div>
 - <div class="btn-line" th:if="${is_fans}">
 - <a href="javascript:void(0)"
 - data-th-attr="data-uid=${user.id},opt-type=follow"
 - class="btn-o btn-green-o js-concern-follow"
 - th:if="${user.isFriend!=2}">关注</a>
 - <a href="javascript:void(0)"
 - data-th-attr="data-uid=${user.id},opt-type=follow"
 - class="btn-o btn-green-o js-concern-follow"
 - style="display: none;"
 - th:if="${user.isFriend==2}">关注</a>
 - <a href="javascript:void(0)"
 - data-th-attr="data-uid=${user.id},opt-type=notfollow"
 - class="btn-o btn-gray-o js-concern-mutual"
 - th:if="${user.isFriend!=2}"
 - style="display: none;">互相关注</a>
 - <a href="javascript:void(0)"
 - data-th-attr="data-uid=${user.id},opt-type=notfollow"
 - class="btn-o btn-gray-o js-concern-mutual"
 - th:if="${user.isFriend==2}">互相关注</a>
 - <a href="/u/2478917/messages?uid=3078817"
 - target="_blank"
 - class="btn-o btn-gray-o js-concern-msg">私信</a>
 - </div>
 - </div>
 - </li>
 - </ul>
 - </div>
 - <div class="clear"></div>
 - <!--分页-->
 - <div id="pagenation" th:if="${userPage.totalPages >= 2}">
 - <nav aria-label="Page navigation" th:object="${userPage}">
 - <ul class="pagination"
 - data-th-attr="data-type=${is_follows}?follows:fans">
 - <li data-th-classappend="*{first} ? 'disabled' : ''">
 - <a href="javascript:void(0)"
 - data-th-attr="pageIndex=${userPage.number}"
 - aria-label="Previous">
 - <span aria-hidden="true">上一页</span>
 - </a>
 - </li>
 - <li th:each="i: ${#numbers.sequence(1, userPage.totalPages)}"
 - data-th-classappend="${(userPage.number + 1) eq i} ? 'active' : ''">
 - <a href="javascript:void(0)"
 - data-th-attr="pageIndex=${i}">
 - <span aria-hidden="true" th:text="${i}"></span>
 - </a>
 - </li>
 - <li data-th-classappend="*{last} ? 'disabled' : ''">
 - <a href="javascript:void(0)"
 - data-th-attr="pageIndex=${userPage.number} + 2"
 - aria-label="Next">
 - <span aria-hidden="true">下一页</span>
 - </a>
 - </li>
 - </ul>
 - </nav>
 - </div>
 - <div class="nodata" th:if="${userPage.totalElements == 0}">
 - <span th:if="${is_follows}">您还没有关注任何用户</span>
 - <span th:if="${is_follows}">您还没有任何粉丝</span>
 - </div>
 - </div>
 - </div>
 - </div>
 - </div>
 - </div>
 - </div>
 
JS
- //重新获取数据
 - $(document).on('click', '.relationship-tab-btn', function () {
 - var _ctx = $("meta[name='ctx']").attr("content");
 - var url = _ctx + "/manage/relationships/" + $(this).attr("data-type");
 - $.ajax({
 - url: url,
 - data: {async: true},
 - success: function (data) {
 - $(".tab-content").html(data)
 - },
 - error: function () {
 - layer.msg("出现错误,请尝试刷新页面!", {icon: 2, anim: 6});
 - }
 - });
 - });
 - //分页
 - $(document).on('click', '.pagination a', function () {
 - var _ctx = $("meta[name='ctx']").attr("content");
 - var page = $(this).attr('pageIndex');
 - var data_type = $(this).parents("ul").attr("data-type");
 - var url = _ctx + "/manage/relationships/" + data_type;
 - $.ajax({
 - url: url,
 - data: {
 - async: true,
 - page: page,
 - },
 - success: function (data) {
 - $(".tab-content").html(data)
 - },
 - error: function () {
 - layer.msg("出现错误,请尝试刷新页面!", {icon: 2, anim: 6});
 - }
 - });
 - });
 - //取消关注
 - $(document).on('click', '.js-concern-already,.js-concern-mutual', function () {
 - var current = $(this);
 - var _ctx = $("meta[name='ctx']").attr("content");
 - var token = $("meta[name='_csrf']").attr("content");
 - var header = $("meta[name='_csrf_header']").attr("content");
 - var url = _ctx + "/manage/relationships/";
 - $.ajax({
 - url: url,
 - type: 'POST',
 - data: {
 - optType: current.attr('opt-type'),
 - userId: current.attr('data-uid'),
 - },
 - beforeSend: function (request) {
 - request.setRequestHeader(header, token); // 添加 CSRF Token
 - },
 - success: function (data) {
 - current.hide();
 - current.prev("a").show();
 - current.parents(".box").find(".fan-size").html(data.body);
 - },
 - error: function () {
 - layer.msg("出现错误,请尝试刷新页面!", {icon: 2, anim: 6});
 - }
 - });
 - });
 - //关注
 - $(document).on('click', '.js-concern-follow', function () {
 - var current = $(this);
 - var _ctx = $("meta[name='ctx']").attr("content");
 - var token = $("meta[name='_csrf']").attr("content");
 - var header = $("meta[name='_csrf_header']").attr("content");
 - var url = _ctx + "/manage/relationships/";
 - $.ajax({
 - url: url,
 - type: 'POST',
 - data: {
 - optType: current.attr('opt-type'),
 - userId: current.attr('data-uid'),
 - },
 - beforeSend: function (request) {
 - request.setRequestHeader(header, token); // 添加 CSRF Token
 - },
 - success: function (data) {
 - current.hide();
 - current.next("a").show();
 - current.parents(".box").find(".fan-size").html(data.body);
 - },
 - error: function () {
 - layer.msg("出现错误,请尝试刷新页面!", {icon: 2, anim: 6});
 - }
 - });
 - });
 
CSS
- ol, ul {
 - list-style: none;
 - }
 - .concern-list {
 - padding-top: 20px;
 - padding-bottom: 20px;
 - width: 100%;
 - }
 - .concern-list ul {
 - margin-left: -18px;
 - }
 - .concern-list .box {
 - float: left;
 - width: 32%;
 - padding: 20px;
 - background-color: #f8fafc;
 - margin-left: 1%;
 - margin-bottom: 15px;
 - min-height: 114px;
 - }
 - .concern-list .left-img {
 - float: left;
 - position: relative;
 - width: 40px;
 - height: 40px;
 - top: 0;
 - }
 - .concern-list .left-img .top_head {
 - position: absolute;
 - top: 0;
 - border-radius: 25px;
 - width: 40px;
 - height: 40px;
 - z-index: 1;
 - }
 - .concern-list .rightright-c {
 - margin-left: 50px;
 - }
 - .concern-list .rightright-c .title {
 - font-weight: 700;
 - color: #07111b;
 - padding-bottom: 8px;
 - width: 100%;
 - }
 - .concern-list .rightright-c .title .nickname {
 - text-overflow: ellipsis;
 - overflow: hidden;
 - whitewhite-space: nowrap;
 - max-width: 60%;
 - display: inline-block;
 - vertical-align: middle;
 - }
 - .concern-list .rightright-c .desc {
 - text-overflow: ellipsis;
 - overflow: hidden;
 - whitewhite-space: nowrap;
 - min-height: 18px;
 - }
 - .concern-list .rightright-c .desc, .concern-list .rightright-c .fs-line {
 - color: #93999f;
 - padding-bottom: 8px;
 - font-size: 12px;
 - }
 - .concern-list .rightright-c .desc, .concern-list .rightright-c .fs-line {
 - color: #93999f;
 - padding-bottom: 8px;
 - font-size: 12px;
 - }
 - .concern-list .rightright-c .fs-line .u-target {
 - color: #93999f!important;
 - }
 - .concern-list .rightright-c .fs-line .group {
 - display: inline-block;
 - }
 - em{
 - font-style: normal;
 - font-weight: 400;
 - }
 - .concern-list .rightright-c .fs-line .u-target {
 - color: #93999f!important;
 - }
 - concern-list .u-margin-l-5 {
 - margin-left: 5px;
 - }
 - .concern-list .hide {
 - display: none;
 - }
 - .concern-list .btn-gray-o {
 - border: 1px solid #d0d6d9;
 - color: #787d82;
 - background-color: #fff;
 - margin-right: 14px;
 - }
 - .concern-list .btn-o {
 - padding: 6px 0;
 - margin-bottom: 0;
 - font-size: 12px;
 - font-weight: 400;
 - line-height: 1.42857143;
 - whitewhite-space: nowrap;
 - vertical-align: middle;
 - cursor: pointer;
 - width: 76px;
 - display: block;
 - float: left;
 - }
 - .concern-list .btn-o{
 - text-align: center;
 - }
 - .concern-list .btn-green-o {
 - border: 1px solid #00b43c;
 - color: #00b43c;
 - background-color: #fff;
 - margin-right: 14px;
 - }
 - .nodata {
 - height: 420px;
 - line-height: 420px;
 - font-size: 18px;
 - color: #b5b9bc;
 - text-align: center;
 - }
 
本文地址:https://liuyanzhao.com/8077.html

                            
                                


                
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏