思维导图

写在前面

这个模块的功能不是网课里的内容,全部都是我自己实现的。前端的界面参考了之前的web大作业和机器人界面的代码,后端都是一些很基础的东西。

后端编写更改图像API

新建service/user/account/GetphotoService接口

1
2
3
4
5
6
7
package com.example.backend.service.user.account;

import java.util.Map;

public interface GetphotoService {
public Map<String, String> getPhoto(Map<String, String> data);
}

service/impl/user/account/GetphotoImpl中实现该接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.backend.service.impl.user.account;

import com.example.backend.mapper.UserMapper;
import com.example.backend.pojo.User;
import com.example.backend.service.impl.utils.UserDetailsImpl;
import com.example.backend.service.user.account.GetphotoService;
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 GetphotoImpl implements GetphotoService {
@Autowired
private UserMapper userMapper;

@Override
public Map<String, String> getPhoto(Map<String, String> data) {
UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
UserDetailsImpl loginUser = (UserDetailsImpl) authentication.getPrincipal();
User user = loginUser.getUser();
Map<String, String> map = new HashMap<>();
String url = data.get("url");

if (url == null || url.length() == 0) {
map.put("error_message", "url is empty");
return map;
}
System.out.println(url);
User newUser = new User(user.getId(), user.getUsername(), user.getPassword(),
url);
userMapper.updateById(newUser);
map.put("error_message", "success");
return map;
}
}

controller/user/account中实现GetphotoController类,用于前端调用后端的API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.example.backend.controller.user.account;

import com.example.backend.service.user.account.GetphotoService;
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 GetphotoController {
@Autowired
private GetphotoService getphotoService;

@PostMapping("/user/account/getphoto/")
public Map<String, String> getPhoto(@RequestParam Map<String, String> data) {
return getphotoService.getPhoto(data);
}
}

后端展示图像API

由于前端的v-for绑定需要uniqueid,所以单穿一个图片url是不够的。为此在utils包里新建一个辅助类PhotoUtil,这个类的成员变量包含图片的url和图片的id。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.example.backend.utils;

public class PhotoUtil {
private int id;
private String url;

public PhotoUtil(int id, String url) {
this.id = id;
this.url = url;
}

public int getId() {
return id;
}

public String getUrl() {
return url;
}
}

新建service/user/account/GetphotoService接口

1
2
3
4
5
6
7
8
9
10
package com.example.backend.service.user.account;

import com.example.backend.utils.PhotoUtil;

import java.util.List;

public interface ShowphotoService {
public List<PhotoUtil> showphoto();
}

service/impl/user/account/GetphotoImpl中实现该接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.example.backend.service.impl.user.account;

import com.example.backend.service.user.account.ShowphotoService;
import com.example.backend.utils.PhotoUtil;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class ShowphotoServiceImpl implements ShowphotoService {
@Override
public List<PhotoUtil> showphoto() {
List<String> photos = new ArrayList<>();
/*
在Photos里add想要加入的图片链接
*/
List<PhotoUtil> ans = new ArrayList<>();
for (int i = 0; i < photos.size(); i++) {
PhotoUtil photoUtil = new PhotoUtil(i + 1, photos.get(i));
ans.add(photoUtil);
}
return ans;
}
}

controller/user/account中实现GetphotoController类,用于前端调用后端的API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.example.backend.controller.user.account;

import com.example.backend.service.user.account.ShowphotoService;
import com.example.backend.utils.PhotoUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class ShowphotoController {
@Autowired
private ShowphotoService showphotoService;
@GetMapping("/user/account/showphoto/")
public List<PhotoUtil> showphoto() {
return showphotoService.showphoto();
}
}

前端调试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const jwt_token = localStorage.getItem("jwt_token");
$.ajax({
url: "http://127.0.0.1:3000/user/account/showphoto/",
type: "get",
headers: {
Authorization: "Bearer " + jwt_token,
},
success(resp) {
console.log(resp);
},
error(resp) {
console.log(resp);
}
})
$.ajax({
url: "http://127.0.0.1:3000/user/account/getphoto/",
type: "post",
data: {
url: "sadkfl;sadjfl;askdjf;lsadkf;lajdfl",
},
headers: {
Authorization: "Bearer " + jwt_token,
},
success(resp) {
console.log(resp);
},
error(resp) {
console.log(resp);
}
})

若前端控制台能输出后端发送过来的信息,说明API编写正确。

前端更改导航栏

加入以下代码,让更改图像的页面在导航栏中显示

1
2
3
4
5
6
7

<li>
<routerLink class="dropdown-item" :to="{name: 'user_photo_index'}"> 更改头像 </routerLink>
</li>
<li>
<hr class="dropdown-divider">
</li>

前端更新路由

1
2
3
4
5
6
7
8
9
10
import UserAccountPhotoIndexView from '../views/user/account/UserAccountPhotoIndexView.vue'

{
path: "/user/photo/",
name: "user_photo_index",
component: UserAccountPhotoIndexView,
meta: {
requestAuth: true,
}
},

编写更改头像

views/user/account新建UserAccountPhotoIndexView.vue文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<template>

<div class="container">
<div class="row">
<div class="col-3">
<div class="card" style="margin-top: 20px;">
<div class="card-body">
<img class="img-fluid" :src="$store.state.user.photo" alt="" style="width: 19.2vw; height: 19.2vw;">
</div>
</div>
</div>
<div class="col-9">
<div class="card" style="margin-top: 20px;">
<div class="card-header">
<span style="font-size: 130%">更改头像</span>
</div>

<div class="card-body">
<span v-for="photo in photos" :key="photo.id">
<span >
<img :src="photo.url" alt="" class="img-thumbnail ten" @click="changephoto(photo)">
</span>
</span>
</div>

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

</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<script >
import $ from 'jquery'
import { ref } from 'vue'
import store from '../../../store';

export default {
setup() {
const jwt_token = localStorage.getItem("jwt_token");
let photos = ref([]);
$.ajax({
url: "http://127.0.0.1:3000/user/account/showphoto/",
type: "get",
headers: {
Authorization: "Bearer " + jwt_token,
},
success(resp) {
photos.value = resp;
},
})
const changephoto = (photo) => {
$.ajax({
url: "http://127.0.0.1:3000/user/account/getphoto/",
type: "post",
headers: {
Authorization: "Bearer " + jwt_token,
},
data: {
url: photo.url,
},
success(resp) {
if (resp.error_message === "success") {
alert("头像更改成功!");
store.state.user.photo = photo.url;
}
},
})
}

return {
photos,
changephoto,
}
}
}

</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
<style scoped>
.img-thumbnail {
height: 19.2vw;
width: 19.2vw;
margin: 0.5vw;
}

.ten:hover {
box-shadow: 2px 2px 10px lightgray;
transition: 300ms;
}

</style>

最终效果

无标题