parent
74808ae9fa
commit
932ed5ed5a
10 changed files with 473 additions and 127 deletions
Binary file not shown.
@ -0,0 +1,96 @@ |
||||
<template> |
||||
<div class="search"> |
||||
<form> |
||||
<input |
||||
v-model="searchText" |
||||
type="text" |
||||
placeholder="输入搜索内容..." |
||||
/> |
||||
<button v-on:click.prevent="searchArticles"></button> |
||||
</form> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { ref } from "vue"; |
||||
import router from "@/router/index"; |
||||
|
||||
export default { |
||||
name: "SearchButton", |
||||
setup() { |
||||
let searchText = ref(""); |
||||
const searchArticles = () => { |
||||
const text = searchText.value.trim(); |
||||
if (text.charAt(0) !== "") { |
||||
router.push({ name: "home", query: { search: text } }); |
||||
} |
||||
}; |
||||
return { |
||||
searchText, |
||||
searchArticles, |
||||
}; |
||||
}, |
||||
}; |
||||
</script> |
||||
|
||||
<style scoped> |
||||
.search { |
||||
padding-top: 22px; |
||||
} |
||||
|
||||
/* 搜索框样式 */ |
||||
* { |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
form { |
||||
position: relative; |
||||
width: 20vw; |
||||
margin: 0 auto; |
||||
} |
||||
|
||||
input, |
||||
button { |
||||
outline: none; |
||||
} |
||||
|
||||
input { |
||||
border-color: gray; |
||||
width: 100%; |
||||
height: 30px; |
||||
padding-left: 13px; |
||||
padding-right: 46px; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
} |
||||
|
||||
button { |
||||
border: none; |
||||
height: 30px; |
||||
width: 30px; |
||||
cursor: pointer; |
||||
position: absolute; |
||||
} |
||||
|
||||
.search input { |
||||
border: 2px solid gray; |
||||
border-radius: 5px; |
||||
background: transparent; |
||||
top: 0; |
||||
right: 0; |
||||
} |
||||
|
||||
.search button { |
||||
background: gray; |
||||
border-radius: 0 5px 5px 0; |
||||
width: 45px; |
||||
top: 0; |
||||
right: 0; |
||||
} |
||||
|
||||
.search button:before { |
||||
content: "搜索"; |
||||
font-size: 13px; |
||||
color: white; |
||||
} |
||||
</style> |
@ -0,0 +1,59 @@ |
||||
import $ from 'jquery'; |
||||
|
||||
const authorization = async () => { |
||||
const storage = localStorage; |
||||
|
||||
let haslogin = false; |
||||
// 用户名
|
||||
let username = storage.getItem('username_blog'); |
||||
// 过期时间
|
||||
const expired_time = Number(storage.getItem("expired_time")); |
||||
console.log("expired_time ",new Date(expired_time).toLocaleString()); |
||||
// 当前时间
|
||||
const current = new Date().getTime(); |
||||
// 刷新令牌
|
||||
const refreshToken = storage.getItem("refresh_blog"); |
||||
// 未过期
|
||||
if (expired_time > current) { |
||||
haslogin = true; |
||||
console.log('authorization success'); |
||||
} |
||||
// 初始tokeng过期,则由刷新令牌申请新的token
|
||||
else if (refreshToken !== null) { |
||||
try { |
||||
$.ajax({ |
||||
url: "http://127.0.0.1:6789/api/token/refresh/", |
||||
type: "POST", |
||||
async: false, |
||||
data: { |
||||
refresh: refreshToken, |
||||
}, |
||||
success(resp) { |
||||
const nextExpiredTime = new Date().getTime() + 60000; |
||||
storage.setItem("access_blog", resp.access); |
||||
storage.removeItem("refresh_blog"); // 移除刷新令牌
|
||||
console.log( |
||||
"令牌刷新时间: ", |
||||
new Date().toLocaleString() |
||||
); |
||||
storage.setItem("expired_time", nextExpiredTime); |
||||
haslogin = true; |
||||
}, |
||||
}); |
||||
}catch(err){ |
||||
storage.clear(); |
||||
haslogin = false; |
||||
console.log('authorization err'); |
||||
} |
||||
|
||||
} else { |
||||
storage.clear(); // 清除所有有效信息
|
||||
haslogin = false; |
||||
console.log('authorization exp'); |
||||
} |
||||
|
||||
console.log('authorization done'); |
||||
return [haslogin, username]; |
||||
} |
||||
|
||||
export default authorization; |
@ -0,0 +1,205 @@ |
||||
<template> |
||||
<BlogHeader ref="header" /> |
||||
<div id="user-center"> |
||||
<h3>更新资料信息</h3> |
||||
<form> |
||||
<div class="form-elem"> |
||||
<span>用户名:</span> |
||||
<input |
||||
v-model="username" |
||||
type="text" |
||||
placeholder="输入用户名" |
||||
/> |
||||
</div> |
||||
|
||||
<div class="form-elem"> |
||||
<span>新密码:</span> |
||||
<input |
||||
v-model="password" |
||||
type="password" |
||||
placeholder="输入密码" |
||||
autocomplete="true" |
||||
/> |
||||
</div> |
||||
|
||||
<div class="form-elem"> |
||||
<button v-on:click.prevent="changeInfo">更新</button> |
||||
</div> |
||||
|
||||
<div class="form-elem"> |
||||
<button |
||||
v-on:click.prevent="showingDeleteAlert=true" |
||||
class="delete-btn" |
||||
> |
||||
删除用户 |
||||
</button> |
||||
<div :class="{ shake: showingDeleteAlert }"> |
||||
<button |
||||
v-if="showingDeleteAlert" |
||||
class="confirm-btn" |
||||
@click.prevent="confirmDelete" |
||||
> |
||||
确定? |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</form> |
||||
</div> |
||||
<BlogFooter /> |
||||
</template> |
||||
|
||||
<script> |
||||
import BlogHeader from "@/components/BlogHeader.vue"; |
||||
import BlogFooter from "@/components/BlogFooter.vue"; |
||||
import authorization from "@/utils/authorization"; |
||||
import $ from "jquery"; |
||||
const storage = localStorage; |
||||
export default { |
||||
name: "UserCenter", |
||||
components: { BlogHeader, BlogFooter }, |
||||
data: function () { |
||||
return { |
||||
username: "", |
||||
password: "", |
||||
token: "", |
||||
showingDeleteAlert: false, |
||||
}; |
||||
}, |
||||
mounted() { |
||||
this.username = storage.getItem("username_blog"); |
||||
}, |
||||
methods: { |
||||
confirmDelete() { |
||||
const that = this; |
||||
authorization().then(function (response) { |
||||
if (response[0]) { |
||||
// 获取令牌 |
||||
that.token = storage.getItem("access_blog"); |
||||
$.ajax({ |
||||
url: 'http://127.0.0.1:6789/api/user/' + that.username + '/', |
||||
type: 'DELETE', |
||||
headers: { |
||||
Authorization: "Bearer " + that.token |
||||
}, |
||||
success(resp) { |
||||
console.log(resp); |
||||
storage.clear(); |
||||
that.$router.push({ name: "home" }); |
||||
} |
||||
}) |
||||
} |
||||
}); |
||||
}, |
||||
changeInfo() { |
||||
const that = this; |
||||
authorization().then(function (response) { |
||||
if (response[0] === false) { |
||||
window.alert("登录已过期, 请重新登录!"); |
||||
storage.clear(); |
||||
that.$router.push({ name: "login" }); |
||||
return; |
||||
} |
||||
// 密码不能少于6位 |
||||
|
||||
if (that.password.length >= 0 && that.password.length < 6) { |
||||
window.alert("密码太短了"); |
||||
return; |
||||
} |
||||
|
||||
// 旧的用户名 |
||||
const oldName = storage.getItem("username_blog"); |
||||
// 表单数据 |
||||
let data = {}; |
||||
if (that.username !== "") { |
||||
data.username = that.username; |
||||
} |
||||
data.password = that.password; |
||||
that.token = storage.getItem("access_blog"); |
||||
// 修改用户名或密码 |
||||
$.ajax({ |
||||
url: "http://127.0.0.1:6789/api/user/" + oldName + "/", |
||||
type: "PATCH", |
||||
data: data, |
||||
headers: { |
||||
Authorization: "Bearer " + that.token, |
||||
}, |
||||
success(resp) { |
||||
window.alert("修改成功"); |
||||
const name = resp.username; |
||||
storage.setItem("username_blog", name); |
||||
// 跳转到用户界面 |
||||
that.$router.push({ |
||||
name: "UserCenter", |
||||
params: { username: name }, |
||||
}); |
||||
that.$refs.header.refresh(); |
||||
}, |
||||
}); |
||||
}); |
||||
}, |
||||
}, |
||||
}; |
||||
</script> |
||||
|
||||
<style scoped> |
||||
#user-center { |
||||
text-align: center; |
||||
} |
||||
|
||||
.form-elem { |
||||
padding: 10px; |
||||
} |
||||
|
||||
input { |
||||
height: 25px; |
||||
padding-left: 10px; |
||||
} |
||||
|
||||
button { |
||||
height: 35px; |
||||
cursor: pointer; |
||||
border: none; |
||||
outline: none; |
||||
background: gray; |
||||
color: whitesmoke; |
||||
border-radius: 5px; |
||||
width: 250px; |
||||
} |
||||
|
||||
.confirm-btn { |
||||
width: 80px; |
||||
background-color: darkorange; |
||||
} |
||||
|
||||
.delete-btn { |
||||
background-color: darkred; |
||||
margin-bottom: 10px; |
||||
} |
||||
|
||||
.shake { |
||||
animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; |
||||
transform: translate3d(0, 0, 0); |
||||
backface-visibility: hidden; |
||||
perspective: 1000px; |
||||
} |
||||
|
||||
@keyframes shake { |
||||
10%, |
||||
90% { |
||||
transform: translate3d(-1px, 0, 0); |
||||
} |
||||
20%, |
||||
80% { |
||||
transform: translate3d(2px, 0, 0); |
||||
} |
||||
30%, |
||||
50%, |
||||
70% { |
||||
transform: translate3d(-4px, 0, 0); |
||||
} |
||||
40%, |
||||
60% { |
||||
transform: translate3d(4px, 0, 0); |
||||
} |
||||
} |
||||
</style> |
Loading…
Reference in new issue