建表 -> 实体类 -> Mapper -> Service -> Controller
pojo
package com.kill9.backend.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Activity {
@TableId(type = IdType.AUTO)
private Integer id;//在pojo里最好用Integer,否则会报警告
private Integer userId;//pojo里要用驼峰命名法和数据库的下划线对应
private String photo;
private String content;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" ,timezone = "Asia/Shanghai")
private Date createtime;
}
mapper
package com.kill9.backend.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface ActivityMapper extends BaseMapper<ActivityMapper> {
}
service
package com.kill9.backend.service.impl.user.activity;
import com.kill9.backend.mapper.ActivityMapper;
import com.kill9.backend.pojo.Activity;
import com.kill9.backend.pojo.User;
import com.kill9.backend.service.impl.utils.UserDetailsImpl;
import com.kill9.backend.service.user.activity.AddActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Service
public class AddActivityServiceImpl implements AddActivityService {
@Autowired
private ActivityMapper activityMapper;
@Override
public Map<String, String> add(Map<String, String> data) {
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
UserDetailsImpl loginUser = (UserDetailsImpl) authenticationToken.getPrincipal();
User user = loginUser.getUser();
Map<String,String> map = new HashMap<>();
String content = data.get("content");
if (content == null || content.length() == 0) {
map.put("error_message", "内容不能为空");
return map;
}
Date date = new Date();
Activity activity = new Activity(null,user.getId(),user.getPhoto(),content,date);
activityMapper.insert(activity);
map.put("error_message","success");
return map;
}
}
controller
package com.kill9.backend.controller.user;
import com.kill9.backend.service.user.activity.AddActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
public class AddActivityController {
@Autowired
private AddActivityService addActivityService;
@PostMapping("/user/activity/add")
public Map<String,String> add(@RequestParam Map<String,String> data){
return addActivityService.add(data);
}
}
实现前端个人页面展示
navbar
<template>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container">
<a class="navbar-brand">MySpace</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarText">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" >Friends</a>
</li>
</ul>
<ul class="navbar-nav" v-if="!$store.state.user.is_login">
<li class="nav-item">
<a class="nav-link active" aria-current="page" >Login</a>
</li>
<li class="nav-item">
<a class="nav-link" >Register</a>
</li>
</ul>
<ul class="navbar-nav" v-else>
<li class="nav-item">
<a class="nav-link active" aria-current="page" >
</a>
</li>
<li class="nav-item">
<a class="nav-link" style="cursor: pointer;">Exit</a>
</li>
</ul>
</div>
</div>
</nav>
</template>
<script>
import {useStore} from 'vuex';
export default{
name:"NavBar",
setup() {
const store = useStore();
const logout = () =>{
store.commit('logout');
};
return {
logout,
}
}
}
</script>
<style scoped>
</style>
userinfoindexview.vue
<template>
<NavBar/>
</template>
<script>
import NavBar from '@/components/userinfo/NavBar.vue';
export default{
components:{
NavBar,
}
}
</script>
<style scoped>
</style>
完成后端三个api 增删查 ,不需要修改帖子
1 add
package com.kill9.backend.service.impl.user.activity;
import com.kill9.backend.mapper.ActivityMapper;
import com.kill9.backend.pojo.Activity;
import com.kill9.backend.pojo.User;
import com.kill9.backend.service.impl.utils.UserDetailsImpl;
import com.kill9.backend.service.user.activity.AddActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Service
public class AddActivityServiceImpl implements AddActivityService {
@Autowired
private ActivityMapper activityMapper;
@Override
public Map<String, String> add(Map<String, String> data) {
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
UserDetailsImpl loginUser = (UserDetailsImpl) authenticationToken.getPrincipal();
User user = loginUser.getUser();
Map<String,String> map = new HashMap<>();
String content = data.get("content");
if (content == null || content.length() == 0) {
map.put("error_message", "内容不能为空");
return map;
}
Date date = new Date();
Activity activity = new Activity(null,user.getId(),user.getPhoto(),content,date);
activityMapper.insert(activity);
map.put("error_message","success");
return map;
}
}
2 getlist
package com.kill9.backend.service.impl.user.activity;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kill9.backend.mapper.ActivityMapper;
import com.kill9.backend.pojo.Activity;
import com.kill9.backend.pojo.User;
import com.kill9.backend.service.impl.utils.UserDetailsImpl;
import com.kill9.backend.service.user.activity.GetActivityListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class GetActivityListServiceImpl implements GetActivityListService {
@Autowired
private ActivityMapper activityMapper;
@Override
public List<Activity> getList() {
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
UserDetailsImpl loginUser =(UserDetailsImpl) authenticationToken.getPrincipal();
User user = loginUser.getUser();
QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id",user.getId());
return activityMapper.selectList(queryWrapper);
}
}
3 delete
package com.kill9.backend.service.impl.user.activity;
import com.kill9.backend.mapper.ActivityMapper;
import com.kill9.backend.pojo.Activity;
import com.kill9.backend.pojo.Bot;
import com.kill9.backend.pojo.User;
import com.kill9.backend.service.impl.utils.UserDetailsImpl;
import com.kill9.backend.service.user.activity.RemoveActivityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;
@Service
public class RemoveActivityServiceImpl implements RemoveActivityService {
@Autowired
private ActivityMapper activityMapper;
@Override
public Map<String, String> remove(Map<String, String> data) {
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
UserDetailsImpl loginUser = (UserDetailsImpl) authenticationToken.getPrincipal();
User user = loginUser.getUser();
int activity_id = Integer.parseInt(data.get("activity_id"));
Map<String,String> map = new HashMap<>();
Activity activity = activityMapper.selectById(activity_id);
if (activity == null) {
map.put("error_message", "帖子不存在或已被删除");
return map;
}
if (!activity.getUserId().equals(user.getId())) {
map.put("error_message", "没有权限删除该帖子");
return map;
}
activityMapper.deleteById(activity_id);
map.put("error_message", "success");
return map;
}
}
实现前端
<template>
<ContentBase>
<div class="row">
<div class="col-3">
<!-- ActivityInfo -->
<div class="card" id="user">
<div class="card-body">
<div class="row">
<div class="col-4 img-field">
<img class="img-fluid" :src="$store.state.user.photo" alt="">
</div>
<div class="col-8 userinfo">
<div class="username">{{$store.state.user.username}}</div>
<div class="fans">Followers: {{$store.state.user.followerCount}}</div>
<div>
<button type="button" class="btn btn-primary btn-sm info-btn">Follow</button>
<button type="button" class="btn btn-warning btn-sm info-btn">Cancel</button>
</div>
</div>
</div>
</div>
</div>
<!-- ActivityWrite -->
<div class="card edit-field">
<div class="card-body">
<label for="edit-post" class="form-label">Edit</label>
<textarea v-model="content" class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
<button @click="submitPost" type="button" class="btn btn-primary btn-sm edit-btn">post</button>
</div>
</div>
</div>
<div class="col-9">
<!-- ActivityPosts -->
<div class="card">
<div class="card-body">
<h1>Activity</h1>
<div>
<div v-for="post in posts" :key="post.id" class="card single-post">
<div class="card single-post">
<div class="card-body">
<span class="content">{{post.content}}</span>
<span class="create-time">{{post.createtime}}</span>
<button @click="deletePost(post.id)" type="button" class="btn btn-danger btn-sm delete-btn">
Delete
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</ContentBase>
</template>
<script>
import ContentBase from '@/components/userinfo/ContentBase.vue';
import {useStore} from 'vuex';
import {ref} from 'vue';
import $ from 'jquery';
export default {
name: 'ActivityView',
components: {
ContentBase,
},
setup(){
const store = useStore();
let posts = ref([]);
let content = ref("");
const refresh_posts = () => {
$.ajax({
url: "http://127.0.0.1:3000/user/activity/getlist/",
type: "get",
headers: {
Authorization: "Bearer " + store.state.user.token,
},
success(resp) {
console.log(resp);
posts.value = resp;
}
});
}
refresh_posts();
const submitPost = () =>{
$.ajax({
url: "http://127.0.0.1:3000/user/activity/add/",
type: "post",
headers: {
Authorization: "Bearer " + store.state.user.token,
},
data:{
content:content.value,
},
success(resp) {
console.log(resp);
content.value="";
refresh_posts();
}
});
}
const deletePost=(postid)=>{
$.ajax({
url: "http://127.0.0.1:3000/user/activity/remove/",
type: "post",
headers: {
Authorization: "Bearer " + store.state.user.token,
},
data:{
activity_id:postid,
},
success(resp) {
console.log(resp);
refresh_posts();
}
});
}
return{
submitPost,
posts,
content,
deletePost,
}
}
}
</script>
<style scoped>
img{
border-radius: 50%;
}
#user{
background-color: pink;
}
.username{
font-weight: bold;
}
.fans{
font-size: 12px;
color: gray;
}
.content{
display: inline-block;
width: 300px;
}
.create-time{
display: inline-block;
font-size: 12px;
color: gray;
padding-left: 70%;
}
.img-field{
display: flex;
flex-direction: column;
justify-content: center;
}
.userinfo{
text-align: left;
}
.single-post{
margin: 10px;
}
.delete-btn{
float: right;
}
.edit-btn{
margin-top: 10px;
float: right;
}
.info-btn{
padding: 2px 4px;
font-size: 12px;
margin-right: 5px;
}
</style>
完成首页页面
<template>
<ContentField>
<h1>Events</h1>
<ContentBase>
<div class="card user" v-for="post in posts" :key="post.id">
<div class="card-body">
<div class="row">
<div class="col-1 img-field">
<img class="img-fluid" :src="post.photo" alt="">
</div>
<div class="col-11 userinfo">
<div class="username">{{post.username}}</div>
<div class="content">{{post.content}}
</div>
<div class="create-time">{{post.createtime}}</div>
</div>
</div>
</div>
</div>
</ContentBase>
</ContentField>
</template>
<script>
import ContentField from '../../components/ContentField.vue';
import ContentBase from '@/components/userinfo/ContentBase.vue';
import { ref } from 'vue';
import $ from 'jquery';
import { useStore } from 'vuex';
export default{
components:{
ContentField,
ContentBase,
},
setup(){
const jwt_token = localStorage.getItem("jwt_token");
const store = useStore();
if(jwt_token){
store.commit("updateToken",jwt_token);
store.dispatch("getinfo",{
success(){
store.commit("updatePullingInfo",false);
},
error(){
store.commit("updatePullingInfo",false);
}
})
}else{
store.commit("updatePullingInfo",false);
}
let posts = ref([]);
$.ajax({
url: "http://127.0.0.1:3000/user/all/",
type: "get",
success(resp) {
posts.value = resp;
}
});
return{
posts,
}
}
}
</script>
<style scoped>
.user{
margin-top: 15px;
cursor: pointer;
}
img{
border-radius: 50%;
}
.username{
font-weight: bold;
height: 50%;
}
.userinfo{
text-align: left;
}
.user:hover{
box-shadow: 2px 2px 15px grey;
transition: 350ms;
}
.img-field{
display: flex;
flex-direction: column;
justify-content: center;
}
.create-time{
font-size: 12px;
color: gray;
margin-top: 7px;
float: right;
}
</style>
controller
package com.kill9.backend.controller.user;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kill9.backend.mapper.ActivityMapper;
import com.kill9.backend.mapper.UserMapper;
import com.kill9.backend.pojo.Activity;
import com.kill9.backend.pojo.User;
import com.kill9.backend.service.user.activity.GetActivityListService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
public class UserController {
@Autowired
private GetActivityListService getActivityListService;
/**
* 查询所有用户
*/
@GetMapping("/user/all/")
public List<Activity> getAll(){
return getActivityListService.getOtherLists();
}
}
完成效果