完成用户模块后端接口
This commit is contained in:
parent
068e8b9a0f
commit
a8a7fadcb1
|
@ -0,0 +1,34 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
||||
|
||||
/cypress/videos/
|
||||
/cypress/screenshots/
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
*.tsbuildinfo
|
||||
*.exe
|
||||
/storage
|
||||
/deploy
|
||||
/.idea
|
|
@ -0,0 +1,52 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"bbs/app/provider/user"
|
||||
"github.com/Superdanda/hade/framework/contract"
|
||||
"github.com/Superdanda/hade/framework/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func AuthMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
envService := c.MustMake(contract.EnvKey).(contract.Env)
|
||||
userService := c.MustMake(user.UserKey).(user.Service)
|
||||
// 如果在调试模式下,根据参数的user_id 获取信息
|
||||
if envService.AppEnv() == contract.EnvDevelopment {
|
||||
userID, exist := c.DefaultQueryInt64("user_id", 0)
|
||||
if exist {
|
||||
authUser, _ := userService.GetUser(c, userID)
|
||||
if authUser != nil {
|
||||
c.Set("auth_user", authUser)
|
||||
c.Next()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
token, err := c.Cookie("hade_bbs")
|
||||
if err != nil || token == "" {
|
||||
c.ISetStatus(http.StatusUnauthorized).IText("请登录后操作")
|
||||
return
|
||||
}
|
||||
|
||||
authUser, err := userService.VerifyLogin(c, token)
|
||||
if err != nil || authUser == nil {
|
||||
c.ISetStatus(http.StatusUnauthorized).IText("请登录后操作")
|
||||
return
|
||||
}
|
||||
|
||||
c.Set("auth_user", authUser)
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// GetAuthUser 获取已经验证的用户
|
||||
func GetAuthUser(c *gin.Context) *user.User {
|
||||
t, exist := c.Get("auth_user")
|
||||
if !exist {
|
||||
return nil
|
||||
}
|
||||
return t.(*user.User)
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/Superdanda/hade/framework/gin"
|
||||
)
|
||||
|
||||
func ResponseHandler() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Next()
|
||||
fmt.Println("response handler")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"bbs/app/http/middleware/auth"
|
||||
"bbs/app/http/middleware/response"
|
||||
"bbs/app/provider/user"
|
||||
"github.com/Superdanda/hade/framework/gin"
|
||||
)
|
||||
|
||||
type UserApi struct{}
|
||||
|
||||
// RegisterRoutes 注册路由
|
||||
func RegisterRoutes(r *gin.Engine) error {
|
||||
api := &UserApi{}
|
||||
|
||||
if !r.IsBind(user.UserKey) {
|
||||
r.Bind(&user.UserProvider{})
|
||||
}
|
||||
|
||||
userGroup := r.Group("/user")
|
||||
userGroup.Use(response.ResponseHandler())
|
||||
{
|
||||
// 登录
|
||||
userGroup.POST("/login", api.Login)
|
||||
// 登出
|
||||
userGroup.GET("/logout", auth.AuthMiddleware(), api.Logout)
|
||||
// 注册
|
||||
userGroup.POST("/register", api.Register)
|
||||
// 注册验证
|
||||
userGroup.GET("/register/verify", api.Verify)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"bbs/app/provider/user"
|
||||
"github.com/Superdanda/hade/framework/gin"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type loginParam struct {
|
||||
UserName string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required,gte=6"`
|
||||
}
|
||||
|
||||
// Login 代表登录
|
||||
// @Summary 用户登录
|
||||
// @accept json
|
||||
// @produce json
|
||||
// @Tags user
|
||||
// @Param loginParam body loginParam true "login with param"
|
||||
// @Success 200 string Token "token"
|
||||
// @Router /user/login [post]
|
||||
func (api *UserApi) Login(c *gin.Context) {
|
||||
userService := c.MustMake(user.UserKey).(user.Service)
|
||||
param := &loginParam{}
|
||||
if err := c.ShouldBind(param); err != nil {
|
||||
c.ISetStatus(http.StatusBadRequest).IText("参数错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 登录
|
||||
model := &user.User{
|
||||
UserName: param.UserName,
|
||||
Password: param.Password,
|
||||
}
|
||||
|
||||
userWithToken, err := userService.Login(c, model)
|
||||
if err != nil {
|
||||
c.ISetStatus(http.StatusInternalServerError).IText(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 输出
|
||||
c.ISetOkStatus().IText(userWithToken.Token)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"bbs/app/http/middleware/auth"
|
||||
"bbs/app/provider/user"
|
||||
"github.com/Superdanda/hade/framework/gin"
|
||||
)
|
||||
|
||||
// Logout 代表登出
|
||||
// @Summary 用户登出
|
||||
// @Description 调用表示用户登出
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags user
|
||||
// @Success 200 {string} Message "用户登出成功"
|
||||
// @Router /user/logout [get]
|
||||
func (api *UserApi) Logout(c *gin.Context) {
|
||||
authUser := auth.GetAuthUser(c)
|
||||
if authUser == nil {
|
||||
c.ISetStatus(500).IText("用户未登录")
|
||||
return
|
||||
}
|
||||
|
||||
userService := c.MustMake(user.UserKey).(user.Service)
|
||||
if err := userService.Logout(c, authUser); err != nil {
|
||||
c.ISetStatus(500).IText(err.Error())
|
||||
return
|
||||
}
|
||||
//c.ISetOkStatus().IText("用户登出成功")
|
||||
c.IRedirect("/#/login")
|
||||
return
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"bbs/app/provider/user"
|
||||
"fmt"
|
||||
"github.com/Superdanda/hade/framework/contract"
|
||||
"github.com/Superdanda/hade/framework/gin"
|
||||
"time"
|
||||
)
|
||||
|
||||
type registerParam struct {
|
||||
UserName string `json:"username" binding:"required"`
|
||||
Password string `json:"password" binding:"required,gte=6"`
|
||||
Email string `json:"email" binding:"required,gte=6"`
|
||||
}
|
||||
|
||||
// Register 注册
|
||||
// @Summary 用户注册
|
||||
// @Description 用户注册接口
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags user
|
||||
// @Param registerParam body registerParam true "注册参数"
|
||||
// @Success 200 string Message "注册成功"
|
||||
// @Router /user/register [post]
|
||||
func (api *UserApi) Register(c *gin.Context) {
|
||||
// 验证参数
|
||||
userService := c.MustMake(user.UserKey).(user.Service)
|
||||
logger := c.MustMake(contract.LogKey).(contract.Log)
|
||||
|
||||
param := ®isterParam{}
|
||||
if err := c.ShouldBind(param); err != nil {
|
||||
c.ISetStatus(400).IText("参数错误 ")
|
||||
return
|
||||
}
|
||||
|
||||
// 登录
|
||||
model := &user.User{
|
||||
UserName: param.UserName,
|
||||
Password: param.Password,
|
||||
Email: param.Email,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
// 注册
|
||||
userWithToken, err := userService.Register(c, model)
|
||||
if err != nil {
|
||||
logger.Error(c, err.Error(), map[string]interface{}{
|
||||
"stack": fmt.Sprintf("%+v", err),
|
||||
})
|
||||
c.ISetStatus(500).IText(err.Error())
|
||||
return
|
||||
}
|
||||
if userWithToken == nil {
|
||||
c.ISetStatus(500).IText("注册失败")
|
||||
return
|
||||
}
|
||||
|
||||
if err := userService.SendRegisterMail(c, userWithToken); err != nil {
|
||||
|
||||
c.ISetStatus(500).IText("发送电子邮件失败")
|
||||
return
|
||||
}
|
||||
|
||||
c.ISetOkStatus().IText("注册成功,请前往邮箱查看邮件")
|
||||
return
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"bbs/app/provider/user"
|
||||
"github.com/Superdanda/hade/framework/gin"
|
||||
)
|
||||
|
||||
// Verify 代表验证注册信息
|
||||
// @Summary 验证注册信息
|
||||
// @Description 使用token验证用户注册信息
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags user
|
||||
// @Param token query string true "注册token"
|
||||
// @Success 200 {string} Message "注册成功,请进入登录页面"
|
||||
// @Router /user/register/verify [get]
|
||||
func (api *UserApi) Verify(c *gin.Context) {
|
||||
// 验证参数
|
||||
userService := c.MustMake(user.UserKey).(user.Service)
|
||||
token := c.Query("token")
|
||||
if token == "" {
|
||||
c.ISetStatus(400).IText("参数错误")
|
||||
return
|
||||
}
|
||||
|
||||
verified, err := userService.VerifyRegister(c, token)
|
||||
if err != nil {
|
||||
c.ISetStatus(500).IText(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if !verified {
|
||||
c.ISetStatus(500).IText("验证错误")
|
||||
return
|
||||
}
|
||||
|
||||
// 输出
|
||||
c.IRedirect("/#/login").IText("注册成功,请进入登录页面")
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package user
|
||||
|
||||
import "time"
|
||||
|
||||
// UserDTO 表示输出到外部的用户信息
|
||||
type UserDTO struct {
|
||||
ID int64 `json:"id,omitempty"`
|
||||
UserName string `json:"user_name,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package user
|
||||
|
||||
import "bbs/app/provider/user"
|
||||
|
||||
// ConvertUserToDTO 将user转换为UserDTO
|
||||
func ConvertUserToDTO(user *user.User) *UserDTO {
|
||||
if user == nil {
|
||||
return nil
|
||||
}
|
||||
return &UserDTO{
|
||||
ID: user.ID,
|
||||
UserName: user.UserName,
|
||||
CreatedAt: user.CreatedAt,
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package http
|
|||
|
||||
import (
|
||||
"bbs/app/http/module/demo"
|
||||
"bbs/app/http/module/user"
|
||||
"github.com/Superdanda/hade/framework/contract"
|
||||
"github.com/Superdanda/hade/framework/gin"
|
||||
ginSwagger "github.com/Superdanda/hade/framework/middleware/gin-swagger"
|
||||
|
@ -22,6 +23,9 @@ func Routes(core *gin.Engine) {
|
|||
core.Use(static.Serve("/", static.LocalFile("./dist", false)))
|
||||
|
||||
err := demo.Register(core)
|
||||
|
||||
err = user.RegisterRoutes(core)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -70,6 +70,128 @@ const docTemplate = `{
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/login": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "用户登录",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "login with param",
|
||||
"name": "loginParam",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/user.loginParam"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "token",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/logout": {
|
||||
"get": {
|
||||
"description": "调用表示用户登出",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "用户登出",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "用户登出成功",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/register": {
|
||||
"post": {
|
||||
"description": "用户注册接口",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "用户注册",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "注册参数",
|
||||
"name": "registerParam",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/user.registerParam"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "注册成功",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/register/verify": {
|
||||
"get": {
|
||||
"description": "使用token验证用户注册信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "验证注册信息",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "注册token",
|
||||
"name": "token",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "注册成功,请进入登录页面",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
@ -83,6 +205,43 @@ const docTemplate = `{
|
|||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"user.loginParam": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"password": {
|
||||
"type": "string",
|
||||
"minLength": 6
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"user.registerParam": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"email",
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string",
|
||||
"minLength": 6
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"minLength": 6
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
|
|
|
@ -63,6 +63,128 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/login": {
|
||||
"post": {
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "用户登录",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "login with param",
|
||||
"name": "loginParam",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/user.loginParam"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "token",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/logout": {
|
||||
"get": {
|
||||
"description": "调用表示用户登出",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "用户登出",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "用户登出成功",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/register": {
|
||||
"post": {
|
||||
"description": "用户注册接口",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "用户注册",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "注册参数",
|
||||
"name": "registerParam",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/user.registerParam"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "注册成功",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/user/register/verify": {
|
||||
"get": {
|
||||
"description": "使用token验证用户注册信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"user"
|
||||
],
|
||||
"summary": "验证注册信息",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "注册token",
|
||||
"name": "token",
|
||||
"in": "query",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "注册成功,请进入登录页面",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
|
@ -76,6 +198,43 @@
|
|||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"user.loginParam": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"password": {
|
||||
"type": "string",
|
||||
"minLength": 6
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"user.registerParam": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"email",
|
||||
"password",
|
||||
"username"
|
||||
],
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string",
|
||||
"minLength": 6
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"minLength": 6
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
|
|
|
@ -7,6 +7,32 @@ definitions:
|
|||
name:
|
||||
type: string
|
||||
type: object
|
||||
user.loginParam:
|
||||
properties:
|
||||
password:
|
||||
minLength: 6
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
- password
|
||||
- username
|
||||
type: object
|
||||
user.registerParam:
|
||||
properties:
|
||||
email:
|
||||
minLength: 6
|
||||
type: string
|
||||
password:
|
||||
minLength: 6
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
required:
|
||||
- email
|
||||
- password
|
||||
- username
|
||||
type: object
|
||||
info:
|
||||
contact:
|
||||
email: yejianfeng
|
||||
|
@ -50,6 +76,85 @@ paths:
|
|||
summary: 获取所有学生
|
||||
tags:
|
||||
- demo
|
||||
/user/login:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
parameters:
|
||||
- description: login with param
|
||||
in: body
|
||||
name: loginParam
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/user.loginParam'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: token
|
||||
schema:
|
||||
type: string
|
||||
summary: 用户登录
|
||||
tags:
|
||||
- user
|
||||
/user/logout:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 调用表示用户登出
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 用户登出成功
|
||||
schema:
|
||||
type: string
|
||||
summary: 用户登出
|
||||
tags:
|
||||
- user
|
||||
/user/register:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 用户注册接口
|
||||
parameters:
|
||||
- description: 注册参数
|
||||
in: body
|
||||
name: registerParam
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/user.registerParam'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 注册成功
|
||||
schema:
|
||||
type: string
|
||||
summary: 用户注册
|
||||
tags:
|
||||
- user
|
||||
/user/register/verify:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 使用token验证用户注册信息
|
||||
parameters:
|
||||
- description: 注册token
|
||||
in: query
|
||||
name: token
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 注册成功,请进入登录页面
|
||||
schema:
|
||||
type: string
|
||||
summary: 验证注册信息
|
||||
tags:
|
||||
- user
|
||||
securityDefinitions:
|
||||
ApiKeyAuth:
|
||||
in: header
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
package user
|
||||
|
||||
const UserKey = "user"
|
||||
|
||||
type Service interface {
|
||||
// 请在这里定义你的方法
|
||||
Foo() string
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
package user
|
||||
|
||||
import (
|
||||
"github.com/Superdanda/hade/framework"
|
||||
)
|
||||
|
||||
type UserProvider struct {
|
||||
framework.ServiceProvider
|
||||
|
||||
c framework.Container
|
||||
}
|
||||
|
||||
func (sp *UserProvider) Name() string {
|
||||
return UserKey
|
||||
}
|
||||
|
||||
func (sp *UserProvider) Register(c framework.Container) framework.NewInstance {
|
||||
return NewUserService
|
||||
}
|
||||
|
||||
func (sp *UserProvider) IsDefer() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (sp *UserProvider) Params(c framework.Container) []interface{} {
|
||||
return []interface{}{c}
|
||||
}
|
||||
|
||||
func (sp *UserProvider) Boot(c framework.Container) error {
|
||||
return nil
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
package user
|
||||
|
||||
import "github.com/Superdanda/hade/framework"
|
||||
|
||||
type UserService struct {
|
||||
container framework.Container
|
||||
}
|
||||
|
||||
func NewUserService(params ...interface{}) (interface{}, error) {
|
||||
container := params[0].(framework.Container)
|
||||
return &UserService{container: container}, nil
|
||||
}
|
||||
|
||||
func (s *UserService) Foo() string {
|
||||
return ""
|
||||
}
|
|
@ -15,4 +15,12 @@ dev: # 调试模式
|
|||
port: 8890 # 后端监听端口,默认8072
|
||||
monitor_folder: "" # 监听文件夹地址,为空或者不填默认为AppFolder
|
||||
frontend: # 前端调试模式配置
|
||||
port: 8889 # 前端监听端口, 默认8071
|
||||
port: 8889 # 前端监听端口, 默认8071
|
||||
|
||||
|
||||
smtp:
|
||||
host: "smtp.126.com"
|
||||
port: 25
|
||||
from: "superdanda@126.com"
|
||||
username: "superdanda"
|
||||
password: "A10337191315."
|
||||
|
|
|
@ -1,23 +1,22 @@
|
|||
conn_max_idle: 10 # 通用配置,连接池最大空闲连接数
|
||||
conn_max_open: 100 # 通用配置,连接池最大连接数
|
||||
conn_max_lifetime: 1h # 通用配置,连接数最大生命周期
|
||||
protocol: tcp # 通用配置,传输协议
|
||||
loc: Local # 通用配置,时区
|
||||
|
||||
default:
|
||||
driver: mysql # 连接驱动
|
||||
dsn: "" # dsn,如果设置了dsn, 以下的所有设置都不生效
|
||||
host: 47.97.21.20 # ip地址
|
||||
port: 3306 # 端口
|
||||
database: questionnaire # 数据库
|
||||
username: root # 用户名
|
||||
password: "kerowsqw34" # 密码
|
||||
charset: utf8mb4 # 字符集
|
||||
collation: utf8mb4_unicode_ci # 字符序
|
||||
timeout: 10s # 连接超时
|
||||
read_timeout: 2s # 读超时
|
||||
write_timeout: 2s # 写超时
|
||||
parse_time: true # 是否解析时间
|
||||
protocol: tcp # 传输协议
|
||||
loc: Local # 时区
|
||||
|
||||
driver: mysql # 连接驱动
|
||||
dsn: "" # dsn,如果设置了dsn, 以下的所有设置都不生效
|
||||
host: 47.97.21.20 # ip地址
|
||||
port: 3306 # 端口
|
||||
database: questionnaire # 数据库
|
||||
username: root # 用户名
|
||||
password: "kerowsqw34" # 密码
|
||||
charset: utf8mb4 # 字符集
|
||||
collation: utf8mb4_unicode_ci # 字符序
|
||||
timeout: 10s # 连接超时
|
||||
read_timeout: 2s # 读超时
|
||||
write_timeout: 2s # 写超时
|
||||
parse_time: true # 是否解析时间
|
||||
protocol: tcp # 传输协议
|
||||
loc: Local # 时区
|
||||
|
||||
|
||||
|
|
8
go.mod
8
go.mod
|
@ -3,8 +3,9 @@ module bbs
|
|||
go 1.23.2
|
||||
|
||||
require (
|
||||
github.com/Superdanda/hade v1.0.2
|
||||
github.com/Superdanda/hade v1.0.4
|
||||
github.com/swaggo/swag v1.16.4
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -21,7 +22,7 @@ require (
|
|||
github.com/robfig/cron/v3 v3.0.0 // indirect
|
||||
github.com/sevlyar/go-daemon v0.1.6 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
gorm.io/gorm v1.25.12 // indirect
|
||||
gorm.io/gorm v1.25.12
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -87,6 +88,7 @@ require (
|
|||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/term v0.25.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gorm.io/driver/clickhouse v0.6.1 // indirect
|
||||
|
@ -126,7 +128,7 @@ require (
|
|||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/crypto v0.28.0
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
)
|
||||
|
|
8
go.sum
8
go.sum
|
@ -36,8 +36,8 @@ github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63n
|
|||
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
|
||||
github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
|
||||
github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/Superdanda/hade v1.0.2 h1:AxlYNeUVO90j+LUHiZW6rg36DbGIXi6gUopURGVMzio=
|
||||
github.com/Superdanda/hade v1.0.2/go.mod h1:z52uXdtEfX25FRCj7YeQOctw6fho9nIaIWc/picNhuA=
|
||||
github.com/Superdanda/hade v1.0.4 h1:NFsH8BBbsHmbedkGHdpjGk3e49GEJtRWU4ENOxp0sfU=
|
||||
github.com/Superdanda/hade v1.0.4/go.mod h1:z52uXdtEfX25FRCj7YeQOctw6fho9nIaIWc/picNhuA=
|
||||
github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
|
||||
github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
|
@ -443,11 +443,15 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
|
|||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
|
|
@ -9,7 +9,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"element-ui": "^2.3.4",
|
||||
"vue": "^2.5.16"
|
||||
"vue": "^2.5.16",
|
||||
"vue-router": "^3.5.3",
|
||||
"vue-style-loader": "^4.1.3",
|
||||
"vuex": "^3.6.2",
|
||||
"axios": "^0.24.0",
|
||||
"js-cookie": "^3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
|
|
16
src/App.vue
16
src/App.vue
|
@ -1,23 +1,15 @@
|
|||
<template>
|
||||
<div id="app">
|
||||
<img src="./assets/logo.png">
|
||||
<div>
|
||||
<el-button @click="startHacking">Start</el-button>
|
||||
</div>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
components: {
|
||||
},
|
||||
methods: {
|
||||
startHacking () {
|
||||
this.$notify({
|
||||
title: 'It works! again',
|
||||
type: 'success',
|
||||
message: 'We\'ve laid the ground work for you. It\'s time for you to build something epic!',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -2,10 +2,14 @@ import Vue from 'vue'
|
|||
import ElementUI from 'element-ui'
|
||||
import 'element-ui/lib/theme-chalk/index.css'
|
||||
import App from './App.vue'
|
||||
import store from './store'
|
||||
import router from './router/index.js'
|
||||
|
||||
Vue.use(ElementUI)
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
router: router,
|
||||
store: store,
|
||||
render: h => h(App)
|
||||
})
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
<script>
|
||||
export default {
|
||||
name: "notfound",
|
||||
data() {
|
||||
return {
|
||||
model: {
|
||||
username: "",
|
||||
password: ""
|
||||
},
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
methods: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="notfound">
|
||||
<el-card>
|
||||
<h2>页面找不到了</h2>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.notfound {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 240px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,25 @@
|
|||
<script>
|
||||
import BBSHeader from './header'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'bbs-header': BBSHeader
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-container>
|
||||
<el-header>
|
||||
<bbs-header></bbs-header>
|
||||
</el-header>
|
||||
<el-main>
|
||||
<router-view></router-view>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,65 @@
|
|||
<script>
|
||||
export default {
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-row type="flex" justify="center" align="middle">
|
||||
<el-col :span="8">
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
<div class="hade_title"><a href="/" id="home-link" title="hadecast">hadecast</a></div>
|
||||
</el-col>
|
||||
<el-col class="" :span="8" :offset="8">
|
||||
<div class="header_name">
|
||||
<router-link class="to-link" :to="{path: '/create'}"><a title="hadecast">我要提问</a></router-link>
|
||||
| jianfengye | <a href="/user/logout" title="hadecast">登出</a></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.hade_title {
|
||||
float: left;
|
||||
vertical-align: top;
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
margin: 0 15px 0 0;
|
||||
line-height: 34px;
|
||||
padding-top: 10px;
|
||||
}
|
||||
|
||||
.header_name {
|
||||
float: right;
|
||||
font-size: 13px;
|
||||
font-weight: 400;
|
||||
margin: 0 15px 0 0;
|
||||
line-height: 34px;
|
||||
padding-top: 10px;
|
||||
padding-top: 10px;
|
||||
background-color: transparent;
|
||||
color: #486e9b;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.header_name > a {
|
||||
background-color: transparent;
|
||||
color: #486e9b;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.hade_title > a {
|
||||
background-color: transparent;
|
||||
color: #486e9b;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.el-header {
|
||||
background-color: #409EFF;
|
||||
text-align: center;
|
||||
line-height: 80px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,94 @@
|
|||
<script>
|
||||
|
||||
export default {
|
||||
name: "login",
|
||||
data() {
|
||||
return {
|
||||
model: {
|
||||
username: "",
|
||||
password: ""
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleLogin() {
|
||||
this.$store.dispatch('user/login', this.model).then(() => {
|
||||
this.$router.push({path: this.redirect || '/'})
|
||||
}).catch(() => {
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="login">
|
||||
<el-card>
|
||||
<h2>登录</h2>
|
||||
<el-form
|
||||
class="login-form"
|
||||
>
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="model.username" placeholder="用户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
placeholder="密码"
|
||||
type="password"
|
||||
v-model="model.password"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-col class="register">
|
||||
还没有账号?请点击
|
||||
<router-link class="to-link" :to="{path: '/register'}">
|
||||
<el-link type="primary">注册</el-link>
|
||||
</router-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="login-button"
|
||||
type="primary"
|
||||
native-type="submit"
|
||||
@click="handleLogin"
|
||||
block
|
||||
>登录
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.to-link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.register {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.login {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.login-button {
|
||||
width: 100%;
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.login-form {
|
||||
width: 390px;
|
||||
}
|
||||
|
||||
.forgot-password {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,100 @@
|
|||
<script setup>
|
||||
import request from '../../utils/request'
|
||||
|
||||
export default {
|
||||
name: "register",
|
||||
data() {
|
||||
return {
|
||||
form: {
|
||||
username: '',
|
||||
password: '',
|
||||
email: '',
|
||||
repassword: ''
|
||||
},
|
||||
loading: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
submitForm: function(e) {
|
||||
if (this.form.repassword !== this.form.password) {
|
||||
this.$message.error("两次输入密码不一致");
|
||||
return;
|
||||
}
|
||||
const that = this;
|
||||
request({
|
||||
url: '/user/register',
|
||||
method: 'post',
|
||||
data: this.form
|
||||
}).then(function (response) {
|
||||
debugger
|
||||
const msg = response.data
|
||||
that.$message.success(msg);
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="register">
|
||||
<el-card>
|
||||
<h2>注册</h2>
|
||||
<el-form v-model="form" class="register-form">
|
||||
<el-form-item >
|
||||
<el-input v-model="form.username" placeholder="用户名" ></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item >
|
||||
<el-input v-model="form.email" placeholder="邮箱"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item >
|
||||
<el-input
|
||||
placeholder="密码"
|
||||
type="password"
|
||||
v-model="form.password"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item >
|
||||
<el-input
|
||||
placeholder="确认密码"
|
||||
type="password"
|
||||
v-model="form.repassword"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
:loading="loading"
|
||||
class="login-button"
|
||||
type="primary"
|
||||
native-type="submit"
|
||||
@click="submitForm"
|
||||
block
|
||||
>注册</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.register {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.login-button {
|
||||
width: 100%;
|
||||
margin-top: 40px;
|
||||
}
|
||||
.register-form {
|
||||
width: 390px;
|
||||
}
|
||||
.forgot-password {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.send_verify_code{
|
||||
|
||||
}
|
||||
</style>
|
|
@ -50,16 +50,16 @@ module.exports = (options = {}) => ({
|
|||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
'~': resolve(__dirname, 'src')
|
||||
'@': resolve(__dirname, 'src')
|
||||
},
|
||||
extensions: ['.js', '.vue', '.json', '.css']
|
||||
},
|
||||
devServer: {
|
||||
host: '127.0.0.1',
|
||||
port: 8010,
|
||||
port: 8890,
|
||||
proxy: {
|
||||
'/api/': {
|
||||
target: 'http://127.0.0.1:8080',
|
||||
target: 'http://127.0.0.1:8890',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/api': ''
|
||||
|
|
54
yarn.lock
54
yarn.lock
|
@ -170,6 +170,13 @@ autoprefixer@^6.3.1, autoprefixer@^6.6.0:
|
|||
postcss "^5.2.16"
|
||||
postcss-value-parser "^3.2.3"
|
||||
|
||||
axios@^0.24.0:
|
||||
version "0.24.0"
|
||||
resolved "https://registry.npmmirror.com/axios/-/axios-0.24.0.tgz"
|
||||
integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==
|
||||
dependencies:
|
||||
follow-redirects "^1.14.4"
|
||||
|
||||
babel-code-frame@^6.11.0, babel-code-frame@^6.22.0:
|
||||
version "6.22.0"
|
||||
resolved "http://registry.npm.taobao.org/babel-code-frame/download/babel-code-frame-6.22.0.tgz"
|
||||
|
@ -1742,6 +1749,11 @@ flatten@^1.0.2:
|
|||
resolved "http://registry.npm.taobao.org/flatten/download/flatten-1.0.2.tgz"
|
||||
integrity sha512-6u/bzbUK+6iOENlqGFkl94EqdAL/FVRhxMWbAE0OBmRsBl64BESxvVRD3CWdilAeka/3WlEZP+0MrKvtYpYFQQ==
|
||||
|
||||
follow-redirects@^1.14.4:
|
||||
version "1.15.9"
|
||||
resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz"
|
||||
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
|
||||
|
||||
for-in@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "http://registry.npm.taobao.org/for-in/download/for-in-1.0.2.tgz"
|
||||
|
@ -2207,6 +2219,11 @@ js-base64@^2.1.9:
|
|||
resolved "http://registry.npm.taobao.org/js-base64/download/js-base64-2.1.9.tgz"
|
||||
integrity sha512-f+5mYh8iF7FlF7zgmj/yqvvYQUHI0kAxGiLjIfNxZzqJ7RQNc4sjgp8crVJw0Kzv2O6aFGZWgMTnO71I9utHSg==
|
||||
|
||||
js-cookie@^3.0.1:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.npmmirror.com/js-cookie/-/js-cookie-3.0.5.tgz"
|
||||
integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==
|
||||
|
||||
js-tokens@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "http://registry.npm.taobao.org/js-tokens/download/js-tokens-3.0.1.tgz"
|
||||
|
@ -2310,16 +2327,7 @@ loader-utils@^0.2.16:
|
|||
json5 "^0.5.0"
|
||||
object-assign "^4.0.1"
|
||||
|
||||
loader-utils@^1.0.2:
|
||||
version "1.1.0"
|
||||
resolved "http://registry.npm.taobao.org/loader-utils/download/loader-utils-1.1.0.tgz"
|
||||
integrity sha512-gkD9aSEG9UGglyPcDJqY9YBTUtCLKaBK6ihD2VP1d1X60lTfFspNZNulGBBbUZLkPygy4LySYHyxBpq+VhjObQ==
|
||||
dependencies:
|
||||
big.js "^3.1.3"
|
||||
emojis-list "^2.0.0"
|
||||
json5 "^0.5.0"
|
||||
|
||||
loader-utils@^1.1.0:
|
||||
loader-utils@^1.0.2, loader-utils@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "http://registry.npm.taobao.org/loader-utils/download/loader-utils-1.1.0.tgz"
|
||||
integrity sha512-gkD9aSEG9UGglyPcDJqY9YBTUtCLKaBK6ihD2VP1d1X60lTfFspNZNulGBBbUZLkPygy4LySYHyxBpq+VhjObQ==
|
||||
|
@ -4000,10 +4008,23 @@ vue-loader@^13.3.0:
|
|||
vue-style-loader "^3.0.0"
|
||||
vue-template-es2015-compiler "^1.6.0"
|
||||
|
||||
vue-router@^3.5.3:
|
||||
version "3.6.5"
|
||||
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-3.6.5.tgz"
|
||||
integrity sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==
|
||||
|
||||
vue-style-loader@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmmirror.com/vue-style-loader/-/vue-style-loader-3.0.1.tgz"
|
||||
integrity sha512-SjeCPpS6yWZwBOXsjayw8F2rqtFmjgmRsSMJQOTBZmaJVt1c+vLN6dBppeiIiQ4BGahYGiBvLfbCBoiKMoxJAQ==
|
||||
version "3.1.2"
|
||||
resolved "https://registry.npmmirror.com/vue-style-loader/-/vue-style-loader-3.1.2.tgz"
|
||||
integrity sha512-ICtVdK/p+qXWpdSs2alWtsXt9YnDoYjQe0w5616j9+/EhjoxZkbun34uWgsMFnC1MhrMMwaWiImz3K2jK1Yp2Q==
|
||||
dependencies:
|
||||
hash-sum "^1.0.2"
|
||||
loader-utils "^1.0.2"
|
||||
|
||||
vue-style-loader@^4.1.3:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.npmmirror.com/vue-style-loader/-/vue-style-loader-4.1.3.tgz"
|
||||
integrity sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==
|
||||
dependencies:
|
||||
hash-sum "^1.0.2"
|
||||
loader-utils "^1.0.2"
|
||||
|
@ -4021,11 +4042,16 @@ vue-template-es2015-compiler@^1.6.0:
|
|||
resolved "https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz"
|
||||
integrity sha512-x3LV3wdmmERhVCYy3quqA57NJW7F3i6faas++pJQWtknWT+n7k30F4TVdHvCLn48peTJFRvCpxs3UuFPqgeELg==
|
||||
|
||||
vue@^2.5.16, vue@^2.5.2:
|
||||
vue@^2.0.0, vue@^2.5.16, vue@^2.5.2:
|
||||
version "2.5.16"
|
||||
resolved "https://registry.npmmirror.com/vue/-/vue-2.5.16.tgz"
|
||||
integrity sha512-/ffmsiVuPC8PsWcFkZngdpas19ABm5mh2wA7iDqcltyCTwlgZjHGeJYOXkBMo422iPwIcviOtrTCUpSfXmToLQ==
|
||||
|
||||
vuex@^3.6.2:
|
||||
version "3.6.2"
|
||||
resolved "https://registry.npmmirror.com/vuex/-/vuex-3.6.2.tgz"
|
||||
integrity sha512-ETW44IqCgBpVomy520DT5jf8n0zoCac+sxWnn+hMe/CzaSejb/eVw2YToiXYX+Ex/AuHHia28vWTq4goAexFbw==
|
||||
|
||||
watchpack@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "http://registry.npm.taobao.org/watchpack/download/watchpack-1.3.1.tgz"
|
||||
|
|
Loading…
Reference in New Issue