feat: 个人信息页面
This commit is contained in:
@@ -4,7 +4,7 @@ db:
|
|||||||
host: localhost
|
host: localhost
|
||||||
port: 3306
|
port: 3306
|
||||||
user: root
|
user: root
|
||||||
password: 123456
|
password: fangyili
|
||||||
database: se
|
database: se
|
||||||
redis:
|
redis:
|
||||||
host: localhost
|
host: localhost
|
||||||
|
|||||||
12157
SourceTrace/gorm-log.txt
12157
SourceTrace/gorm-log.txt
File diff suppressed because one or more lines are too long
@@ -1,9 +1,13 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/NothAmor/SourceTrace/cli"
|
"github.com/NothAmor/SourceTrace/cli"
|
||||||
"github.com/NothAmor/SourceTrace/common"
|
"github.com/NothAmor/SourceTrace/common"
|
||||||
|
"github.com/NothAmor/SourceTrace/cron"
|
||||||
"github.com/NothAmor/SourceTrace/initial"
|
"github.com/NothAmor/SourceTrace/initial"
|
||||||
|
"github.com/NothAmor/SourceTrace/spider"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@@ -19,7 +23,7 @@ func main() {
|
|||||||
initial.InitRPC()
|
initial.InitRPC()
|
||||||
|
|
||||||
// cron job
|
// cron job
|
||||||
// cron.InitCron()
|
cron.InitCron()
|
||||||
|
|
||||||
// db init command
|
// db init command
|
||||||
cli.RootCmd.AddCommand(cli.DBInitCmd)
|
cli.RootCmd.AddCommand(cli.DBInitCmd)
|
||||||
@@ -28,7 +32,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// start spider
|
// start spider
|
||||||
// go spider.NextStep(time.Now())
|
go spider.NextStep(time.Now())
|
||||||
|
|
||||||
// start rpc server
|
// start rpc server
|
||||||
if err := common.RPC.Serve("tcp", *common.RPC_SERVER_ADDR); err != nil {
|
if err := common.RPC.Serve("tcp", *common.RPC_SERVER_ADDR); err != nil {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ type (
|
|||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
LoginResult struct {
|
LoginResult struct {
|
||||||
|
ID int `json:"id"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Role int `json:"role"`
|
Role int `json:"role"`
|
||||||
Msg string `json:"msg"`
|
Msg string `json:"msg"`
|
||||||
|
|||||||
@@ -19,19 +19,49 @@ type UserArgs struct {
|
|||||||
Phone *string `json:"phone"`
|
Phone *string `json:"phone"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseUserArgToUser(userArgs UserArgs) models.Users {
|
func ParseUserArgToUser(userArgs UserArgs) (user models.Users) {
|
||||||
return models.Users{
|
// return models.Users{
|
||||||
ID: userArgs.ID,
|
// ID: userArgs.ID,
|
||||||
Username: *userArgs.Username,
|
// Username: *userArgs.Username,
|
||||||
Password: *userArgs.Password,
|
// Password: *userArgs.Password,
|
||||||
Name: *userArgs.Name,
|
// Name: *userArgs.Name,
|
||||||
Gender: *userArgs.Gender,
|
// Gender: *userArgs.Gender,
|
||||||
Avatar: *userArgs.Avatar,
|
// Avatar: *userArgs.Avatar,
|
||||||
Address: *userArgs.Address,
|
// Address: *userArgs.Address,
|
||||||
Role: *userArgs.Role,
|
// Role: *userArgs.Role,
|
||||||
Email: *userArgs.Email,
|
// Email: *userArgs.Email,
|
||||||
Phone: *userArgs.Phone,
|
// Phone: *userArgs.Phone,
|
||||||
|
// }
|
||||||
|
|
||||||
|
user.ID = userArgs.ID
|
||||||
|
if userArgs.Username != nil {
|
||||||
|
user.Username = *userArgs.Username
|
||||||
}
|
}
|
||||||
|
if userArgs.Password != nil {
|
||||||
|
user.Password = *userArgs.Password
|
||||||
|
}
|
||||||
|
if userArgs.Name != nil {
|
||||||
|
user.Name = *userArgs.Name
|
||||||
|
}
|
||||||
|
if userArgs.Gender != nil {
|
||||||
|
user.Gender = *userArgs.Gender
|
||||||
|
}
|
||||||
|
if userArgs.Avatar != nil {
|
||||||
|
user.Avatar = *userArgs.Avatar
|
||||||
|
}
|
||||||
|
if userArgs.Address != nil {
|
||||||
|
user.Address = *userArgs.Address
|
||||||
|
}
|
||||||
|
if userArgs.Role != nil {
|
||||||
|
user.Role = *userArgs.Role
|
||||||
|
}
|
||||||
|
if userArgs.Email != nil {
|
||||||
|
user.Email = *userArgs.Email
|
||||||
|
}
|
||||||
|
if userArgs.Phone != nil {
|
||||||
|
user.Phone = *userArgs.Phone
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
type UsersResp struct {
|
type UsersResp struct {
|
||||||
|
|||||||
@@ -245,6 +245,7 @@ func (t *Arith) Login(ctx context.Context, loginReq proto.LoginReq, loginResult
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
loginResult.Msg = "登录成功"
|
loginResult.Msg = "登录成功"
|
||||||
|
loginResult.ID = user.ID
|
||||||
loginResult.Username = user.Username
|
loginResult.Username = user.Username
|
||||||
loginResult.Role = user.Role
|
loginResult.Role = user.Role
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -41,6 +41,13 @@ func Login(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Println(loginResult)
|
fmt.Println(loginResult)
|
||||||
|
cookieOfUserID := &http.Cookie{
|
||||||
|
Name: "userID",
|
||||||
|
Value: strconv.Itoa(loginResult.ID),
|
||||||
|
Path: "/",
|
||||||
|
Secure: false,
|
||||||
|
HttpOnly: true,
|
||||||
|
}
|
||||||
cookieOfUsername := &http.Cookie{
|
cookieOfUsername := &http.Cookie{
|
||||||
Name: "username",
|
Name: "username",
|
||||||
Value: loginResult.Username,
|
Value: loginResult.Username,
|
||||||
@@ -55,6 +62,7 @@ func Login(c *gin.Context) {
|
|||||||
Secure: false,
|
Secure: false,
|
||||||
HttpOnly: true,
|
HttpOnly: true,
|
||||||
}
|
}
|
||||||
|
http.SetCookie(c.Writer, cookieOfUserID)
|
||||||
http.SetCookie(c.Writer, cookieOfUsername)
|
http.SetCookie(c.Writer, cookieOfUsername)
|
||||||
http.SetCookie(c.Writer, cookieOfRole)
|
http.SetCookie(c.Writer, cookieOfRole)
|
||||||
|
|
||||||
|
|||||||
40
SourceTraceFront/controllers/myself.go
Normal file
40
SourceTraceFront/controllers/myself.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/NothAmor/SourceTraceFront/common"
|
||||||
|
"github.com/NothAmor/SourceTraceFront/models"
|
||||||
|
"github.com/NothAmor/SourceTraceFront/proto"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Myself(c *gin.Context) {
|
||||||
|
var listUsers []models.Users
|
||||||
|
pageArgs := proto.PageArgs{Page: 1}
|
||||||
|
err := common.RPC.Call(context.Background(), "ListUsers", pageArgs, &listUsers)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("failed to call: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(listUsers) == 0 {
|
||||||
|
c.HTML(http.StatusOK, "myself.html", gin.H{
|
||||||
|
"name": "未登录",
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
userInfo := listUsers[0]
|
||||||
|
fmt.Printf("userInfo:%v\n", userInfo)
|
||||||
|
c.HTML(http.StatusOK, "myself.html", gin.H{
|
||||||
|
"id": userInfo.ID,
|
||||||
|
"name": userInfo.Name,
|
||||||
|
"gender": userInfo.Gender,
|
||||||
|
"avatar": userInfo.Avatar,
|
||||||
|
"address": userInfo.Address,
|
||||||
|
"email": userInfo.Email,
|
||||||
|
"phone": userInfo.Phone,
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ type (
|
|||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
}
|
}
|
||||||
LoginResult struct {
|
LoginResult struct {
|
||||||
|
ID int `json:"id"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
Role int `json:"role"`
|
Role int `json:"role"`
|
||||||
Msg string `json:"msg"`
|
Msg string `json:"msg"`
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ func InitRouter() {
|
|||||||
common.Core.GET("/register", controllers.RegisterPage)
|
common.Core.GET("/register", controllers.RegisterPage)
|
||||||
common.Core.POST("/register", controllers.Register)
|
common.Core.POST("/register", controllers.Register)
|
||||||
|
|
||||||
|
common.Core.GET("/myself", controllers.Myself)
|
||||||
|
|
||||||
userGroup := common.Core.Group("/user")
|
userGroup := common.Core.Group("/user")
|
||||||
userGroup.GET("/listUsers", controllers.ListUsers)
|
userGroup.GET("/listUsers", controllers.ListUsers)
|
||||||
userGroup.POST("/addUser", controllers.AddUser)
|
userGroup.POST("/addUser", controllers.AddUser)
|
||||||
|
|||||||
145
SourceTraceFront/views/myself.html
Normal file
145
SourceTraceFront/views/myself.html
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>个人信息修改</title>
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body, html {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.profile-card {
|
||||||
|
width: 50%;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.profile-image {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.profile-image img {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
.profile-details {
|
||||||
|
flex: 2;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="card profile-card">
|
||||||
|
<div class="card-content" style="width: 100rem;">
|
||||||
|
<div class="profile-image">
|
||||||
|
<img src="{{.avatar}}" alt="头像">
|
||||||
|
</div>
|
||||||
|
<div class="profile-details">
|
||||||
|
<form id="updateProfileForm">
|
||||||
|
<input type="hidden" type="text" value="{{.id}}" name="id" id="id">
|
||||||
|
<div class="input-field">
|
||||||
|
<input id="name" type="text" class="validate" name="name" value="{{.name}}">
|
||||||
|
<label for="name">姓名</label>
|
||||||
|
</div>
|
||||||
|
<div class="input-field">
|
||||||
|
<input id="gender" type="text" class="validate" name="gender" value="{{.gender}}">
|
||||||
|
<label for="gender">性别</label>
|
||||||
|
</div>
|
||||||
|
<div class="input-field">
|
||||||
|
<input id="avatar" type="text" class="validate" name="avatar" value="{{.avatar}}">
|
||||||
|
<label for="avatar">头像URL</label>
|
||||||
|
</div>
|
||||||
|
<div class="input-field">
|
||||||
|
<input id="address" type="text" class="validate" name="address" value="{{.address}}">
|
||||||
|
<label for="address">地址</label>
|
||||||
|
</div>
|
||||||
|
<div class="input-field">
|
||||||
|
<input id="email" type="email" class="validate" name="email" value="{{.email}}">
|
||||||
|
<label for="email">邮箱</label>
|
||||||
|
</div>
|
||||||
|
<div class="input-field">
|
||||||
|
<input id="phone" type="text" class="validate" name="phone" value="{{.phone}}">
|
||||||
|
<label for="phone">手机</label>
|
||||||
|
</div>
|
||||||
|
<button class="btn waves-effect waves-light" type="submit" name="action">更新
|
||||||
|
<i class="material-icons right">send</i>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// 初始化Materialize组件
|
||||||
|
M.updateTextFields();
|
||||||
|
|
||||||
|
// 获取用户数据
|
||||||
|
fetch('/user/listUsers')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
// 假设返回的是一个用户列表,我们取第一个用户作为示例
|
||||||
|
console.log(data.data)
|
||||||
|
let user = data.data[0];
|
||||||
|
document.getElementById('id').value = user.id;
|
||||||
|
document.getElementById('name').value = user.name;
|
||||||
|
document.getElementById('gender').value = user.gender;
|
||||||
|
document.getElementById('avatar').value = user.avatar;
|
||||||
|
document.getElementById('address').value = user.address;
|
||||||
|
document.getElementById('email').value = user.email;
|
||||||
|
document.getElementById('phone').value = user.phone;
|
||||||
|
|
||||||
|
// 更新表单字段状态
|
||||||
|
M.updateTextFields();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新用户数据
|
||||||
|
document.getElementById('updateProfileForm').addEventListener('submit', function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
console.log(this.id.value)
|
||||||
|
// id to int
|
||||||
|
function int(str) {
|
||||||
|
return parseInt(str, 10);
|
||||||
|
}
|
||||||
|
console.log(int(this.id.value))
|
||||||
|
const formData = {
|
||||||
|
id: int(this.id.value),
|
||||||
|
name: this.name.value,
|
||||||
|
gender: this.gender.value,
|
||||||
|
avatar: this.avatar.value,
|
||||||
|
address: this.address.value,
|
||||||
|
email: this.email.value,
|
||||||
|
phone: this.phone.value
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch('/user/updateUser', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(formData)
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
console.log('Success:', data);
|
||||||
|
M.toast({html: '更新成功'});
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
M.toast({html: '更新失败'});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user