CRUD
This commit is contained in:
parent
21401650f1
commit
3fbff92ed8
3
main.go
3
main.go
|
|
@ -31,6 +31,9 @@ func main() {
|
||||||
r.StaticFS("/static", http.FS(fp))
|
r.StaticFS("/static", http.FS(fp))
|
||||||
|
|
||||||
r.GET("/app", m.JWTAuthMiddleware, m.AppPage)
|
r.GET("/app", m.JWTAuthMiddleware, m.AppPage)
|
||||||
|
r.POST("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp)
|
||||||
|
r.PUT("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp)
|
||||||
|
r.DELETE("/app", m.JWTAuthMiddleware, m.CreateUpdateDeleteApp)
|
||||||
r.GET("/login/:username", Test)
|
r.GET("/login/:username", Test)
|
||||||
err := r.Run()
|
err := r.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ type AppModel struct {
|
||||||
SvcName string
|
SvcName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (AppModel) TableName() string {
|
func (*AppModel) TableName() string {
|
||||||
return "app"
|
return "app"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21,3 +21,21 @@ func GetApps(username string) []AppModel {
|
||||||
db.Where("user_name = ?", username).Find(&ans)
|
db.Where("user_name = ?", username).Find(&ans)
|
||||||
return ans
|
return ans
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *AppModel) Update() error {
|
||||||
|
db := DB()
|
||||||
|
db.Save(a)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AppModel) Create() error {
|
||||||
|
db := DB()
|
||||||
|
db.Create(a)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *AppModel) Delete() error {
|
||||||
|
db := DB()
|
||||||
|
db.Delete(a, a.Id)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package k8s_manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -18,3 +19,31 @@ func AppPage(c *gin.Context) {
|
||||||
}
|
}
|
||||||
c.HTML(http.StatusOK, "app_view.html", vm)
|
c.HTML(http.StatusOK, "app_view.html", vm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateUpdateDeleteApp(c *gin.Context) {
|
||||||
|
app := &AppModel{}
|
||||||
|
err := c.BindJSON(app)
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("AddApp")
|
||||||
|
c.JSON(http.StatusBadRequest, gin.H{"msg": "Cannot get data."})
|
||||||
|
} else {
|
||||||
|
username := c.MustGet("username").(string)
|
||||||
|
if username != app.UserName {
|
||||||
|
c.JSON(http.StatusUnauthorized, gin.H{"msg": "user error."})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if c.Request.Method == http.MethodPost {
|
||||||
|
err = app.Create()
|
||||||
|
} else if c.Request.Method == http.MethodPut {
|
||||||
|
err = app.Update()
|
||||||
|
} else if c.Request.Method == http.MethodDelete {
|
||||||
|
err = app.Delete()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
log.WithError(err).Error("CreateUpdateDeleteApp", c.Request.Method)
|
||||||
|
c.JSON(http.StatusInternalServerError, gin.H{"msg": "DB error."})
|
||||||
|
} else {
|
||||||
|
c.JSON(http.StatusOK, gin.H{"msg": "ok"})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -3,6 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<link href="static/css/bootstrap.min.css" rel="stylesheet">
|
<link href="static/css/bootstrap.min.css" rel="stylesheet">
|
||||||
<script src="static/js/bootstrap.bundle.min.js"></script>
|
<script src="static/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="static/js/axios.min.js"></script>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>应用管理</title>
|
<title>应用管理</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -39,6 +40,7 @@
|
||||||
{{ range $i, $v := .Apps }}
|
{{ range $i, $v := .Apps }}
|
||||||
<tr id="app-list-{{ $v.Id }}">
|
<tr id="app-list-{{ $v.Id }}">
|
||||||
<td> {{ inc $i }}</td>
|
<td> {{ inc $i }}</td>
|
||||||
|
<td class="app-field-id" style="display: none;"> {{ $v.Id }}</td>
|
||||||
<td class="app-field-name"> {{ $v.AppName }}</td>
|
<td class="app-field-name"> {{ $v.AppName }}</td>
|
||||||
<td class="app-field-comment"> {{ $v.Comment }}</td>
|
<td class="app-field-comment"> {{ $v.Comment }}</td>
|
||||||
<td class="app-field-image"> {{ $v.Image }}</td>
|
<td class="app-field-image"> {{ $v.Image }}</td>
|
||||||
|
|
@ -47,7 +49,7 @@
|
||||||
<td>
|
<td>
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button class="btn btn-primary" onclick="showModal('app-list-{{ $v.Id }}')">修改</button>
|
<button class="btn btn-primary" onclick="showModal('app-list-{{ $v.Id }}')">修改</button>
|
||||||
<button class="btn btn-danger">删除</button>
|
<button class="btn btn-danger" onclick="deleteApp('{{ $v.Id }}')">删除</button>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -70,10 +72,15 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<input type="text" id="app-id" class="form-control" style="display: none;" disabled/>
|
||||||
|
<input type="text" id="app-username" class="form-control" style="display: none;" disabled
|
||||||
|
value="{{ .Username }}"/>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<label for="app-name" class="form-label">应用名</label>
|
<label for="app-name" class="form-label">应用名</label>
|
||||||
<input type="text" id="app-name" class="form-control" placeholder="只能为字母、数字和下划线" />
|
<input type="text" id="app-name" class="form-control"
|
||||||
|
placeholder="只能为字母、数字和下划线"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
|
|
@ -100,11 +107,20 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
|
||||||
<button type="button" class="btn btn-primary">保存</button>
|
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="updateApp()">保存
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="toast d-flex align-items-center top-0 end-0" id="success-toast">
|
||||||
|
<div class="toast-body">
|
||||||
|
<p id="toast-content"></p>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn-close ms-auto me-2" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|
@ -126,7 +142,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearModalField() {
|
function clearModalField() {
|
||||||
const id_list = ["app-name", "app-image", "app-cmd", "app-env", "app-comment"]
|
const id_list = ["app-id", "app-name", "app-image", "app-cmd", "app-env", "app-comment"]
|
||||||
for (const k of id_list) {
|
for (const k of id_list) {
|
||||||
document.getElementById(k).value = ""
|
document.getElementById(k).value = ""
|
||||||
}
|
}
|
||||||
|
|
@ -146,5 +162,45 @@
|
||||||
(new bootstrap.Modal("#edit-modal")).show()
|
(new bootstrap.Modal("#edit-modal")).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showToast(e) {
|
||||||
|
document.getElementById("toast-content").innerHTML = e.msg
|
||||||
|
t = new bootstrap.Toast(document.getElementById("success-toast"))
|
||||||
|
console.log(t)
|
||||||
|
t.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateApp() {
|
||||||
|
const id_list = ["app-id", "app-name", "app-username", "app-image", "app-cmd", "app-env", "app-comment"]
|
||||||
|
const json_key_list = ["Id", "AppName", "UserName", "Image", "Command", "Env", "Comment"]
|
||||||
|
let appData = {}
|
||||||
|
for (let k in id_list) {
|
||||||
|
appData[json_key_list[k]] = document.getElementById(id_list[k]).value
|
||||||
|
}
|
||||||
|
if (appData['Id']) {
|
||||||
|
appData['Id'] = parseInt(appData['Id'])
|
||||||
|
axios.put("app", appData).then(e => {
|
||||||
|
showToast(e.data)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
appData['Id'] = null
|
||||||
|
axios.post("app", appData).then(e => {
|
||||||
|
console.log(e)
|
||||||
|
showToast(e.data)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteApp(id) {
|
||||||
|
axios.delete("app", {
|
||||||
|
"data": {
|
||||||
|
Id: parseInt(id),
|
||||||
|
Username: document.getElementById("app-username").value
|
||||||
|
}
|
||||||
|
}).then(e => {
|
||||||
|
console.log(e.data)
|
||||||
|
showToast(e.data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in New Issue