feat(api-docs): 更新文档以反映API变化
API文档已更新,包含端点的Base URL更动,以配合新部署的API服务器位置。此外,响应数据的字段名称已根据数据库模型的更新进行调整,确保与返回的数据结构一致。
This commit is contained in:
parent
845876c633
commit
351bf46193
|
@ -0,0 +1,15 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="myValues">
|
||||||
|
<value>
|
||||||
|
<list size="1">
|
||||||
|
<item index="0" class="java.lang.String" itemvalue="post_id" />
|
||||||
|
</list>
|
||||||
|
</value>
|
||||||
|
</option>
|
||||||
|
<option name="myCustomValuesEnabled" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="JavaScriptLibraryMappings">
|
||||||
|
<file url="file://$PROJECT_DIR$/wqyblog_webui" libraries="{jquery-3.6.0, markdown-it}" />
|
||||||
|
</component>
|
||||||
|
</project>
|
32
README.md
32
README.md
|
@ -1,14 +1,22 @@
|
||||||
# 博客 RESTful API 文档
|
# 微博客 RESTful API 文档
|
||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
本 API 提供了一个用于管理博客文章的接口,支持使用 Markdown 格式存储内容,并且支持分页查询。后端基于 Go 语言开发,支持 MySQL 和 PostgreSQL 数据库。
|
本 API 提供了一个用于管理博客文章的接口,支持使用 Markdown 格式存储内容,并且支持分页查询。后端基于 Go 语言开发,支持 MySQL
|
||||||
|
和 PostgreSQL 数据库。
|
||||||
|
|
||||||
## 基本信息
|
## 基本信息
|
||||||
|
|
||||||
- **Base URL**: `https://func-e-wiwafluoqc.cn-shanghai.fcapp.run/api`
|
- **Base URL**: `https://wqyblog-cn-api-eqvsnqpylk.cn-shanghai.fcapp.run/api`
|
||||||
- **Content-Type**: `application/json`
|
- **Content-Type**: `application/json`
|
||||||
- **Authorization**: 使用 JWT 进行身份验证。在所有需要身份验证的请求中,必须在请求头中包含 `Authorization: Bearer {token}`。
|
- **Authorization**: 使用 JWT
|
||||||
|
进行身份验证。在所有需要身份验证的请求中,必须在请求头中包含 `Authorization: Bearer {token}`。
|
||||||
|
|
||||||
|
## 提示
|
||||||
|
|
||||||
|
- 在使用此 API 时,请确保使用 HTTPS 来保护数据传输的安全性。
|
||||||
|
|
||||||
|
- 案例网站:https://wqyblog.cn/
|
||||||
|
|
||||||
## 测试认证密码
|
## 测试认证密码
|
||||||
|
|
||||||
|
@ -60,8 +68,8 @@
|
||||||
"CreatedAt": "2024-08-20T12:00:00Z",
|
"CreatedAt": "2024-08-20T12:00:00Z",
|
||||||
"UpdatedAt": "2024-08-20T12:00:00Z",
|
"UpdatedAt": "2024-08-20T12:00:00Z",
|
||||||
"DeletedAt": null,
|
"DeletedAt": null,
|
||||||
"Title": "First Post",
|
"title": "First Post",
|
||||||
"Content": "Markdown content here..."
|
"content": "Markdown content here..."
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -107,8 +115,8 @@
|
||||||
"CreatedAt": "2024-08-22T12:00:00Z",
|
"CreatedAt": "2024-08-22T12:00:00Z",
|
||||||
"UpdatedAt": "2024-08-22T12:00:00Z",
|
"UpdatedAt": "2024-08-22T12:00:00Z",
|
||||||
"DeletedAt": null,
|
"DeletedAt": null,
|
||||||
"Title": "New Post Title",
|
"title": "New Post Title",
|
||||||
"Content": "Markdown content here..."
|
"content": "Markdown content here..."
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- **说明**: 创建一篇新的博文,并返回创建的博文信息。
|
- **说明**: 创建一篇新的博文,并返回创建的博文信息。
|
||||||
|
@ -133,8 +141,8 @@
|
||||||
"CreatedAt": "2024-08-20T12:00:00Z",
|
"CreatedAt": "2024-08-20T12:00:00Z",
|
||||||
"UpdatedAt": "2024-08-22T13:00:00Z",
|
"UpdatedAt": "2024-08-22T13:00:00Z",
|
||||||
"DeletedAt": null,
|
"DeletedAt": null,
|
||||||
"Title": "Updated Post Title",
|
"title": "Updated Post Title",
|
||||||
"Content": "Updated markdown content..."
|
"content": "Updated markdown content..."
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
- **说明**: 更新指定 `id` 的博文。如果该 `id` 对应的博文不存在,返回 `404` 错误。
|
- **说明**: 更新指定 `id` 的博文。如果该 `id` 对应的博文不存在,返回 `404` 错误。
|
||||||
|
@ -166,7 +174,3 @@ API 在发生错误时会返回以下格式的错误响应:
|
||||||
- **401 Unauthorized**: 需要有效的 JWT 令牌,但令牌未提供或无效。
|
- **401 Unauthorized**: 需要有效的 JWT 令牌,但令牌未提供或无效。
|
||||||
- **404 Not Found**: 请求的资源不存在(如博文不存在)。
|
- **404 Not Found**: 请求的资源不存在(如博文不存在)。
|
||||||
- **400 Bad Request**: 请求参数无效或缺失。
|
- **400 Bad Request**: 请求参数无效或缺失。
|
||||||
|
|
||||||
## 例外情况
|
|
||||||
|
|
||||||
在使用此 API 时,请确保使用 HTTPS 来保护数据传输的安全性。
|
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -3,7 +3,6 @@ module wqyblog_api_go
|
||||||
go 1.23
|
go 1.23
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
|
||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
github.com/jinzhu/gorm v1.9.16
|
github.com/jinzhu/gorm v1.9.16
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
|
@ -23,6 +22,7 @@ require (
|
||||||
github.com/go-playground/validator/v10 v10.22.0 // indirect
|
github.com/go-playground/validator/v10 v10.22.0 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||||
github.com/goccy/go-json v0.10.3 // indirect
|
github.com/goccy/go-json v0.10.3 // indirect
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -39,6 +39,8 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv
|
||||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
|
||||||
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
|
||||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import "github.com/gin-gonic/gin"
|
||||||
|
|
||||||
|
func Cors() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
|
||||||
|
c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
|
||||||
|
if c.Request.Method == "OPTIONS" {
|
||||||
|
c.AbortWithStatus(204)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,8 +2,8 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/dgrijalva/jwt-go"
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
|
@ -28,8 +28,11 @@ func GetPosts(c *gin.Context) {
|
||||||
offset := (page - 1) * limit
|
offset := (page - 1) * limit
|
||||||
|
|
||||||
var posts []models.Post
|
var posts []models.Post
|
||||||
db.DB.Limit(limit).Offset(offset).Find(&posts)
|
|
||||||
|
|
||||||
|
// 按照创建时间降序排序获取帖子
|
||||||
|
db.DB.Order("created_at desc").Limit(limit).Offset(offset).Find(&posts)
|
||||||
|
|
||||||
|
// 返回分页结果
|
||||||
c.JSON(http.StatusOK, gin.H{
|
c.JSON(http.StatusOK, gin.H{
|
||||||
"page": page,
|
"page": page,
|
||||||
"limit": limit,
|
"limit": limit,
|
||||||
|
|
3
main.go
3
main.go
|
@ -11,6 +11,9 @@ func main() {
|
||||||
|
|
||||||
r := gin.Default()
|
r := gin.Default()
|
||||||
|
|
||||||
|
// 开启跨域
|
||||||
|
r.Use(handlers.Cors())
|
||||||
|
|
||||||
r.GET("/", handlers.HalloWorld)
|
r.GET("/", handlers.HalloWorld)
|
||||||
|
|
||||||
r.POST("/api/auth/login", handlers.Login)
|
r.POST("/api/auth/login", handlers.Login)
|
||||||
|
|
10
text.http
10
text.http
|
@ -1,4 +1,4 @@
|
||||||
POST http://localhost:8080/api/auth/login
|
POST http://localhost:18080/api/auth/login
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -7,13 +7,13 @@ Content-Type: application/json
|
||||||
}
|
}
|
||||||
|
|
||||||
###
|
###
|
||||||
POST http://localhost:8080/api/posts
|
POST http://localhost:18080/api/posts
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzI0MTMxNjIxfQ.NZu5hhl7XjT9BdjIPmBAknekNHIavZYh5Xzz39PUzkk
|
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoxNzI0MTUzOTMzfQ.3AleOSoNYIEWF1iSVreNKYnetSeawAfjIqAqWWwU058
|
||||||
|
|
||||||
{
|
{
|
||||||
"title": "New Post Title",
|
"title": "hello world2",
|
||||||
"content": "Markdown content here..."
|
"content": "# Markdown content here...\n## Heading 2\n\n- hello world2\n- wqyblog.cn"
|
||||||
}
|
}
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
|
@ -4,5 +4,7 @@
|
||||||
<exclude-output />
|
<exclude-output />
|
||||||
<content url="file://$MODULE_DIR$/wqyblog_webui" />
|
<content url="file://$MODULE_DIR$/wqyblog_webui" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="jquery-3.6.0" level="application" />
|
||||||
|
<orderEntry type="library" name="markdown-it" level="application" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
|
@ -1,11 +0,0 @@
|
||||||
# editorconfig.org
|
|
||||||
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
indent_size = 2
|
|
||||||
indent_style = space
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
|
@ -1,194 +0,0 @@
|
||||||
## GITATTRIBUTES FOR WEB PROJECTS
|
|
||||||
#
|
|
||||||
# These settings are for any web project.
|
|
||||||
#
|
|
||||||
# Details per file setting:
|
|
||||||
# text These files should be normalized (i.e. convert CRLF to LF).
|
|
||||||
# binary These files are binary and should be left untouched.
|
|
||||||
#
|
|
||||||
# Note that binary is a macro for -text -diff.
|
|
||||||
######################################################################
|
|
||||||
|
|
||||||
## AUTO-DETECT
|
|
||||||
## Handle line endings automatically for files detected as
|
|
||||||
## text and leave all files detected as binary untouched.
|
|
||||||
## This will handle all files NOT defined below.
|
|
||||||
* text=auto
|
|
||||||
|
|
||||||
## SOURCE CODE
|
|
||||||
*.bat text eol=crlf
|
|
||||||
*.coffee text
|
|
||||||
*.css text
|
|
||||||
*.htm text
|
|
||||||
*.html text
|
|
||||||
*.inc text
|
|
||||||
*.ini text
|
|
||||||
*.js text
|
|
||||||
*.json text
|
|
||||||
*.jsx text
|
|
||||||
*.less text
|
|
||||||
*.od text
|
|
||||||
*.onlydata text
|
|
||||||
*.php text
|
|
||||||
*.pl text
|
|
||||||
*.py text
|
|
||||||
*.rb text
|
|
||||||
*.sass text
|
|
||||||
*.scm text
|
|
||||||
*.scss text
|
|
||||||
*.sh text eol=lf
|
|
||||||
*.sql text
|
|
||||||
*.styl text
|
|
||||||
*.tag text
|
|
||||||
*.ts text
|
|
||||||
*.tsx text
|
|
||||||
*.xml text
|
|
||||||
*.xhtml text
|
|
||||||
|
|
||||||
## DOCKER
|
|
||||||
*.dockerignore text
|
|
||||||
Dockerfile text
|
|
||||||
|
|
||||||
## DOCUMENTATION
|
|
||||||
*.markdown text
|
|
||||||
*.md text
|
|
||||||
*.mdwn text
|
|
||||||
*.mdown text
|
|
||||||
*.mkd text
|
|
||||||
*.mkdn text
|
|
||||||
*.mdtxt text
|
|
||||||
*.mdtext text
|
|
||||||
*.txt text
|
|
||||||
AUTHORS text
|
|
||||||
CHANGELOG text
|
|
||||||
CHANGES text
|
|
||||||
CONTRIBUTING text
|
|
||||||
COPYING text
|
|
||||||
copyright text
|
|
||||||
*COPYRIGHT* text
|
|
||||||
INSTALL text
|
|
||||||
license text
|
|
||||||
LICENSE text
|
|
||||||
NEWS text
|
|
||||||
readme text
|
|
||||||
*README* text
|
|
||||||
TODO text
|
|
||||||
|
|
||||||
## TEMPLATES
|
|
||||||
*.dot text
|
|
||||||
*.ejs text
|
|
||||||
*.haml text
|
|
||||||
*.handlebars text
|
|
||||||
*.hbs text
|
|
||||||
*.hbt text
|
|
||||||
*.jade text
|
|
||||||
*.latte text
|
|
||||||
*.mustache text
|
|
||||||
*.njk text
|
|
||||||
*.phtml text
|
|
||||||
*.tmpl text
|
|
||||||
*.tpl text
|
|
||||||
*.twig text
|
|
||||||
|
|
||||||
## LINTERS
|
|
||||||
.babelrc text
|
|
||||||
.csslintrc text
|
|
||||||
.eslintrc text
|
|
||||||
.htmlhintrc text
|
|
||||||
.jscsrc text
|
|
||||||
.jshintrc text
|
|
||||||
.jshintignore text
|
|
||||||
.prettierrc text
|
|
||||||
.stylelintrc text
|
|
||||||
|
|
||||||
## CONFIGS
|
|
||||||
*.bowerrc text
|
|
||||||
*.cnf text
|
|
||||||
*.conf text
|
|
||||||
*.config text
|
|
||||||
.browserslistrc text
|
|
||||||
.editorconfig text
|
|
||||||
.gitattributes text
|
|
||||||
.gitconfig text
|
|
||||||
.gitignore text
|
|
||||||
.htaccess text
|
|
||||||
*.npmignore text
|
|
||||||
*.yaml text
|
|
||||||
*.yml text
|
|
||||||
browserslist text
|
|
||||||
Makefile text
|
|
||||||
makefile text
|
|
||||||
|
|
||||||
## HEROKU
|
|
||||||
Procfile text
|
|
||||||
.slugignore text
|
|
||||||
|
|
||||||
## GRAPHICS
|
|
||||||
*.ai binary
|
|
||||||
*.bmp binary
|
|
||||||
*.eps binary
|
|
||||||
*.gif binary
|
|
||||||
*.ico binary
|
|
||||||
*.jng binary
|
|
||||||
*.jp2 binary
|
|
||||||
*.jpg binary
|
|
||||||
*.jpeg binary
|
|
||||||
*.jpx binary
|
|
||||||
*.jxr binary
|
|
||||||
*.pdf binary
|
|
||||||
*.png binary
|
|
||||||
*.psb binary
|
|
||||||
*.psd binary
|
|
||||||
*.svg text
|
|
||||||
*.svgz binary
|
|
||||||
*.tif binary
|
|
||||||
*.tiff binary
|
|
||||||
*.wbmp binary
|
|
||||||
*.webp binary
|
|
||||||
|
|
||||||
## AUDIO
|
|
||||||
*.kar binary
|
|
||||||
*.m4a binary
|
|
||||||
*.mid binary
|
|
||||||
*.midi binary
|
|
||||||
*.mp3 binary
|
|
||||||
*.ogg binary
|
|
||||||
*.ra binary
|
|
||||||
|
|
||||||
## VIDEO
|
|
||||||
*.3gpp binary
|
|
||||||
*.3gp binary
|
|
||||||
*.as binary
|
|
||||||
*.asf binary
|
|
||||||
*.asx binary
|
|
||||||
*.fla binary
|
|
||||||
*.flv binary
|
|
||||||
*.m4v binary
|
|
||||||
*.mng binary
|
|
||||||
*.mov binary
|
|
||||||
*.mp4 binary
|
|
||||||
*.mpeg binary
|
|
||||||
*.mpg binary
|
|
||||||
*.ogv binary
|
|
||||||
*.swc binary
|
|
||||||
*.swf binary
|
|
||||||
*.webm binary
|
|
||||||
|
|
||||||
## ARCHIVES
|
|
||||||
*.7z binary
|
|
||||||
*.gz binary
|
|
||||||
*.jar binary
|
|
||||||
*.rar binary
|
|
||||||
*.tar binary
|
|
||||||
*.zip binary
|
|
||||||
|
|
||||||
## FONTS
|
|
||||||
*.ttf binary
|
|
||||||
*.eot binary
|
|
||||||
*.otf binary
|
|
||||||
*.woff binary
|
|
||||||
*.woff2 binary
|
|
||||||
|
|
||||||
## EXECUTABLES
|
|
||||||
*.exe binary
|
|
||||||
*.pyc binary
|
|
|
@ -1,19 +0,0 @@
|
||||||
Copyright (c) HTML5 Boilerplate
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
|
@ -15,6 +15,13 @@ html {
|
||||||
text-shadow: none;
|
text-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 去除a标签样式 */
|
||||||
|
a {
|
||||||
|
color: #323232;
|
||||||
|
border: none;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 更好看的默认水平线
|
* 更好看的默认水平线
|
||||||
*/
|
*/
|
||||||
|
@ -92,6 +99,38 @@ body {
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header-button-right {
|
||||||
|
position: absolute;
|
||||||
|
right: 5vw;
|
||||||
|
top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-button-left {
|
||||||
|
position: absolute;
|
||||||
|
left: 5vw;
|
||||||
|
top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
main
|
||||||
|
*/
|
||||||
|
|
||||||
|
.main {
|
||||||
|
flex: 1;
|
||||||
|
width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-content {
|
||||||
|
height: 100%;
|
||||||
|
flex: 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-sidebar {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* ==========================================================================
|
/* ==========================================================================
|
||||||
辅助类
|
辅助类
|
||||||
========================================================================== */
|
========================================================================== */
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html class="no-js" lang="">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title></title>
|
||||||
|
<link rel="stylesheet" href="./css/style.css">
|
||||||
|
|
||||||
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
||||||
|
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
||||||
|
<link rel="apple-touch-icon" href="icon.png">
|
||||||
|
<meta name="theme-color" content="#fafafa">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.main-content {
|
||||||
|
padding: 0 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#post_content {
|
||||||
|
width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#show {
|
||||||
|
width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<div class="header-title">
|
||||||
|
编辑
|
||||||
|
</div>
|
||||||
|
<div class="header-button-left">
|
||||||
|
<a href="./index.html">返回</a><br>
|
||||||
|
<label for="post_title">文章标题:</label><input id="post_title">
|
||||||
|
</div>
|
||||||
|
<div class="header-button-right">
|
||||||
|
<a href="javascript:;" id="save">保存</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
<div class="main-content">
|
||||||
|
<p>Markdown内容</p>
|
||||||
|
<textarea id="post_content" rows="20" cols="100">
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
<div style="background-color: #222222;width: 1px;"></div>
|
||||||
|
<div class="main-content">
|
||||||
|
<p>Markdown预览</p>
|
||||||
|
<div id="show">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
|
||||||
|
<script>
|
||||||
|
// 检查 jQuery 是否已经加载
|
||||||
|
window.jQuery || document.write('<script src="./js/vendor/jquery-3.6.0.min.js"><\/script>');
|
||||||
|
// 检查 markdown-it 是否已经加载
|
||||||
|
window.markdownit || document.write('<script src="./js/vendor/markdown-it.min.js"><\/script>');
|
||||||
|
</script>
|
||||||
|
<script src="./js/const.js"></script>
|
||||||
|
<script src="./js/edit.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -6,42 +6,70 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title></title>
|
<title></title>
|
||||||
<link rel="stylesheet" href="./css/style.css">
|
<link rel="stylesheet" href="./css/style.css">
|
||||||
<meta name="description" content="">
|
|
||||||
|
|
||||||
<meta property="og:title" content="">
|
|
||||||
<meta property="og:type" content="">
|
|
||||||
<meta property="og:url" content="">
|
|
||||||
<meta property="og:image" content="">
|
|
||||||
<meta property="og:image:alt" content="">
|
|
||||||
|
|
||||||
<link rel="icon" href="/favicon.ico" sizes="any">
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
||||||
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
||||||
<link rel="apple-touch-icon" href="icon.png">
|
<link rel="apple-touch-icon" href="icon.png">
|
||||||
|
|
||||||
<link rel="manifest" href="site.webmanifest">
|
|
||||||
<meta name="theme-color" content="#fafafa">
|
<meta name="theme-color" content="#fafafa">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.post-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-item {
|
||||||
|
min-width: 250px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 5px auto;
|
||||||
|
padding: 12px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-title {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-message {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
gap: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div class="header-title">
|
<div class="header-title">
|
||||||
WqyBlog.cn
|
WqyBlog 首页
|
||||||
</div>
|
</div>
|
||||||
<div class="login">
|
<div class="header-button-left"></div>
|
||||||
<a href="login.html">登录</a>
|
<div class="header-button-right">
|
||||||
|
<a href="./login.html">登录</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
|
<div class="post-list">
|
||||||
</div>
|
</div>
|
||||||
<div class="main-sidebar">
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="jquery/dist/jquery.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js"></script>
|
||||||
|
<script>
|
||||||
|
// 检查 jQuery 是否已经加载
|
||||||
|
window.jQuery || document.write('<script src="./js/vendor/jquery-3.6.0.min.js"><\/script>');
|
||||||
|
// 检查 markdown-it 是否已经加载
|
||||||
|
window.markdownit || document.write('<script src="./js/vendor/markdown-it.min.js"><\/script>');
|
||||||
|
</script>
|
||||||
|
<script src="./js/const.js"></script>
|
||||||
<script src="./js/app.js"></script>
|
<script src="./js/app.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1 +1,82 @@
|
||||||
// app.js wqyblog.cn
|
$(function () {
|
||||||
|
Cookie(function () {
|
||||||
|
$('.header-button-left').html(`<a href="./edit.html?s=new">写文章</a>`);
|
||||||
|
$('.header-button-right').html(`<a id="logout" href="javascript:;">退出登录</a>`);
|
||||||
|
$('#logout').click(function () {
|
||||||
|
document.cookie = 'token=;max-age=0'
|
||||||
|
window.location.href = '/'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
/**
|
||||||
|
* URL /posts
|
||||||
|
* 方法 GET
|
||||||
|
* 参数 page limit
|
||||||
|
* 响应
|
||||||
|
* {
|
||||||
|
* "page": 1,
|
||||||
|
* "limit": 10,
|
||||||
|
* "data": [
|
||||||
|
* {
|
||||||
|
* "ID": 1,
|
||||||
|
* "CreatedAt": "2024-08-20T12:00:00Z",
|
||||||
|
* "UpdatedAt": "2024-08-20T12:00:00Z",
|
||||||
|
* "DeletedAt": null,
|
||||||
|
* "Title": "First Post",
|
||||||
|
* "Content": "Markdown content here..."
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* }
|
||||||
|
**/
|
||||||
|
$.ajax({
|
||||||
|
url: `${baseUrl}/posts`,
|
||||||
|
type: 'GET',
|
||||||
|
contentType: 'application/json',
|
||||||
|
success: function (data) {
|
||||||
|
if (Cookie()) {
|
||||||
|
data.data.forEach((item) => {
|
||||||
|
$('.post-list').append(`<div class="post-item"><div class="post-title">${item.title}</div><div class="post-message"><div>创建时间:${item.CreatedAt}</div><div>更新时间:${item.UpdatedAt}</div><div><a href="javascript:;" class="post_edit" data-post_id="${item.ID}">编辑</a> <a href="javascript:;" class="post_delete" data-post_id="${item.ID}">删除</a></div></div><div class="post-content">${md.render(item.content)}</div></div>`);
|
||||||
|
})
|
||||||
|
$('.post_edit').click(function () {
|
||||||
|
// 获取post_id
|
||||||
|
let post_id = $(this).data('post_id')
|
||||||
|
window.location.href = '/edit.html?s=old&id=' + post_id
|
||||||
|
})
|
||||||
|
$('.post_delete').click(function () {
|
||||||
|
// 获取post_id
|
||||||
|
let post_id = $(this).data('post_id')
|
||||||
|
// 询问是否删除
|
||||||
|
if (confirm('确定删除吗?')) {
|
||||||
|
$.ajax({
|
||||||
|
url: `${baseUrl}/posts/${post_id}`,
|
||||||
|
type: 'DELETE',
|
||||||
|
contentType: 'application/json',
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader('Authorization', 'Bearer ' + document.cookie.split('token=')[1].split(';')[0])
|
||||||
|
},
|
||||||
|
success: function (data) {
|
||||||
|
alert('删除成功')
|
||||||
|
window.location.reload()
|
||||||
|
},
|
||||||
|
error: function (xhr, status, error) {
|
||||||
|
if (xhr.status === 401) {
|
||||||
|
alert('请先登录')
|
||||||
|
window.location.href = '/login.html'
|
||||||
|
} else {
|
||||||
|
alert('删除失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data.data.forEach((item) => {
|
||||||
|
$('.post-list').append(`<div class="post-item"><div class="post-title">${item.title}</div><div class="post-message"><div>创建时间:${item.CreatedAt}</div><div>更新时间:${item.UpdatedAt}</div></div><div class="post-content">${md.render(item.content)}</div></div>`);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
error: function (xhr, status, error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
const baseUrl = 'https://wqyblog-cn-api-eqvsnqpylk.cn-shanghai.fcapp.run/api'
|
||||||
|
const md = window.markdownit();
|
||||||
|
|
||||||
|
function Cookie(fn = () => {
|
||||||
|
console.log("yes")
|
||||||
|
}) {
|
||||||
|
// 检查cookie 是否有token
|
||||||
|
if (document.cookie.indexOf('token') !== -1) {
|
||||||
|
fn();
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
$(function () {
|
||||||
|
if (!Cookie()){
|
||||||
|
window.location.href = `/index.html`
|
||||||
|
}
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
if (urlParams.get('s') === 'new') {
|
||||||
|
$('#post_title').val('')
|
||||||
|
$('#post_content').val('')
|
||||||
|
}
|
||||||
|
if (urlParams.get('s') === 'old') {
|
||||||
|
$.ajax({
|
||||||
|
url: `${baseUrl}/posts/${urlParams.get('id')}`,
|
||||||
|
type: 'GET',
|
||||||
|
contentType: 'application/json',
|
||||||
|
success: function (data) {
|
||||||
|
$('#post_title').val(data.title)
|
||||||
|
$('#post_content').val(data.content)
|
||||||
|
$('#show').html(md.render(data.content));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
$('#post_content').on('input', function () {
|
||||||
|
// 获取输入框的值
|
||||||
|
let content = $(this).val()
|
||||||
|
$('#show').html(md.render(content));
|
||||||
|
})
|
||||||
|
|
||||||
|
$('#save').click(function () {
|
||||||
|
// 获取输入框的值
|
||||||
|
let title = $('#post_title').val()
|
||||||
|
let content = $('#post_content').val()
|
||||||
|
if (title === '' || content === '') {
|
||||||
|
alert('请输入标题和内容')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (urlParams.get('s') === 'new') {
|
||||||
|
$.ajax({
|
||||||
|
url: `${baseUrl}/posts`,
|
||||||
|
type: 'POST',
|
||||||
|
data: JSON.stringify({
|
||||||
|
title: title,
|
||||||
|
content: content
|
||||||
|
}),
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader('Authorization', 'Bearer ' + document.cookie.split('token=')[1].split(';')[0])
|
||||||
|
},
|
||||||
|
contentType: 'application/json',
|
||||||
|
success: function (data) {
|
||||||
|
alert('保存成功')
|
||||||
|
window.location.href = `/index.html`
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
alert('保存失败')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (urlParams.get('s') === 'old') {
|
||||||
|
$.ajax({
|
||||||
|
url: `${baseUrl}/posts/${urlParams.get('id')}`,
|
||||||
|
type: 'PUT',
|
||||||
|
data: JSON.stringify({
|
||||||
|
title: title,
|
||||||
|
content: content
|
||||||
|
}),
|
||||||
|
beforeSend: function (xhr) {
|
||||||
|
xhr.setRequestHeader('Authorization', 'Bearer ' + document.cookie.split('token=')[1].split(';')[0])
|
||||||
|
},
|
||||||
|
contentType: 'application/json',
|
||||||
|
success: function (data) {
|
||||||
|
alert('保存成功')
|
||||||
|
window.location.href = `/index.html`
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
|
@ -0,0 +1,35 @@
|
||||||
|
$(function () {
|
||||||
|
$('#login-form').submit(function (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
/**
|
||||||
|
* URL https://func-e-wiwafluoqc.cn-shanghai.fcapp.run/api/auth/login
|
||||||
|
* 方法 POST
|
||||||
|
* 请求体:
|
||||||
|
* {
|
||||||
|
* "username": "admin",
|
||||||
|
* "password": "your_secure_password"
|
||||||
|
* }
|
||||||
|
**/
|
||||||
|
const username = $('#username').val()
|
||||||
|
const password = $('#password').val()
|
||||||
|
$.ajax({
|
||||||
|
url: `${baseUrl}/auth/login`,
|
||||||
|
type: 'POST',
|
||||||
|
data: JSON.stringify({
|
||||||
|
username,
|
||||||
|
password
|
||||||
|
}),
|
||||||
|
contentType: 'application/json',
|
||||||
|
success: function (data) {
|
||||||
|
// cookie 1小时
|
||||||
|
document.cookie = `token=${data.token};max-age=3600`
|
||||||
|
window.location.href = '/'
|
||||||
|
},
|
||||||
|
error: function (xhr, status, error) {
|
||||||
|
$('.login').html(`<h1>登录失败</h1><p>${jQuery.parseJSON(xhr.responseText).error}</p><p><a href="./login.html">重新登录</a></p>`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$('.login').html(`<h1>正在登录中……</h1>`)
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
})
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -3,24 +3,106 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>登录</title>
|
<title></title>
|
||||||
<link rel="stylesheet" href="./css/style.css">
|
<link rel="stylesheet" href="./css/style.css">
|
||||||
<meta name="description" content="">
|
|
||||||
|
|
||||||
<meta property="og:title" content="">
|
|
||||||
<meta property="og:type" content="">
|
|
||||||
<meta property="og:url" content="">
|
|
||||||
<meta property="og:image" content="">
|
|
||||||
<meta property="og:image:alt" content="">
|
|
||||||
|
|
||||||
<link rel="icon" href="/favicon.ico" sizes="any">
|
<link rel="icon" href="/favicon.ico" sizes="any">
|
||||||
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
<link rel="icon" href="/icon.svg" type="image/svg+xml">
|
||||||
<link rel="apple-touch-icon" href="icon.png">
|
<link rel="apple-touch-icon" href="icon.png">
|
||||||
|
|
||||||
<link rel="manifest" href="site.webmanifest">
|
|
||||||
<meta name="theme-color" content="#fafafa">
|
<meta name="theme-color" content="#fafafa">
|
||||||
|
<style>
|
||||||
|
.login {
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#login-form {
|
||||||
|
min-width: 250px;
|
||||||
|
width: 50vw;
|
||||||
|
max-width: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group {
|
||||||
|
margin: 24px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group label {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group input {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
flex: 4;
|
||||||
|
|
||||||
|
/* 删除边框\圆角\背景 */
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
padding-inline: 10px;
|
||||||
|
border-bottom: #333333 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group button {
|
||||||
|
font-size: 1.15rem;
|
||||||
|
padding: 2px 20px;
|
||||||
|
|
||||||
|
/* 删除边框\圆角\背景 */
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background: none;
|
||||||
|
|
||||||
|
border-bottom: #333333 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-group button:hover {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<div class="header-title">
|
||||||
|
WqyBlog 登录
|
||||||
|
</div>
|
||||||
|
<div class="header-button-left">
|
||||||
|
<a href="./index.html">返回</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
<div class="login">
|
||||||
|
<form id="login-form">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="username">用户名</label>
|
||||||
|
<input type="text" id="username" name="username" placeholder="请输入用户名">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">密码</label>
|
||||||
|
<input type="password" id="password" name="password" placeholder="请输入密码">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button type="submit">登录</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script>
|
||||||
|
// 检查 jQuery 是否已经加载
|
||||||
|
window.jQuery || document.write('<script src="./js/vendor/jquery-3.6.0.min.js"><\/script>');
|
||||||
|
</script>
|
||||||
|
<script src="./js/const.js"></script>
|
||||||
|
<script src="./js/login.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,27 +0,0 @@
|
||||||
{
|
|
||||||
"name": " ",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"description": "",
|
|
||||||
"private": true,
|
|
||||||
"keywords": [
|
|
||||||
""
|
|
||||||
],
|
|
||||||
"license": "",
|
|
||||||
"author": "",
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
|
||||||
"start": "webpack serve --open --config webpack.config.dev.js",
|
|
||||||
"build": "webpack --config webpack.config.prod.js"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"copy-webpack-plugin": "^11.0.0",
|
|
||||||
"html-webpack-plugin": "^5.6.0",
|
|
||||||
"webpack": "^5.91.0",
|
|
||||||
"webpack-cli": "^5.1.4",
|
|
||||||
"webpack-dev-server": "^5.0.4",
|
|
||||||
"webpack-merge": "^5.10.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"jquery": "^3.7.1"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
# www.robotstxt.org/
|
|
||||||
|
|
||||||
# Allow crawling of all content
|
|
||||||
User-agent: *
|
|
||||||
Disallow:
|
|
|
@ -1,12 +0,0 @@
|
||||||
{
|
|
||||||
"short_name": "",
|
|
||||||
"name": "",
|
|
||||||
"icons": [{
|
|
||||||
"src": "icon.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "192x192"
|
|
||||||
}],
|
|
||||||
"start_url": "/?utm_source=homescreen",
|
|
||||||
"background_color": "#fafafa",
|
|
||||||
"theme_color": "#fafafa"
|
|
||||||
}
|
|
|
@ -1,12 +0,0 @@
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
entry: {
|
|
||||||
app: './js/app.js',
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
path: path.resolve(__dirname, 'dist'),
|
|
||||||
clean: true,
|
|
||||||
filename: './js/app.js',
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,13 +0,0 @@
|
||||||
const { merge } = require('webpack-merge');
|
|
||||||
const common = require('./webpack.common.js');
|
|
||||||
|
|
||||||
module.exports = merge(common, {
|
|
||||||
mode: 'development',
|
|
||||||
devtool: 'inline-source-map',
|
|
||||||
devServer: {
|
|
||||||
liveReload: true,
|
|
||||||
hot: true,
|
|
||||||
open: true,
|
|
||||||
static: ['./'],
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -1,26 +0,0 @@
|
||||||
const { merge } = require('webpack-merge');
|
|
||||||
const common = require('./webpack.common.js');
|
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
|
||||||
const CopyPlugin = require('copy-webpack-plugin');
|
|
||||||
|
|
||||||
module.exports = merge(common, {
|
|
||||||
mode: 'production',
|
|
||||||
plugins: [
|
|
||||||
new HtmlWebpackPlugin({
|
|
||||||
template: './index.html',
|
|
||||||
}),
|
|
||||||
new CopyPlugin({
|
|
||||||
patterns: [
|
|
||||||
{ from: 'img', to: 'img' },
|
|
||||||
{ from: 'css', to: 'css' },
|
|
||||||
{ from: 'js/vendor', to: 'js/vendor' },
|
|
||||||
{ from: 'icon.svg', to: 'icon.svg' },
|
|
||||||
{ from: 'favicon.ico', to: 'favicon.ico' },
|
|
||||||
{ from: 'robots.txt', to: 'robots.txt' },
|
|
||||||
{ from: 'icon.png', to: 'icon.png' },
|
|
||||||
{ from: '404.html', to: '404.html' },
|
|
||||||
{ from: 'site.webmanifest', to: 'site.webmanifest' },
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
});
|
|
Loading…
Reference in New Issue