wmj-test/template/app_view.html

228 lines
8.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<link href="static/css/bootstrap.min.css" rel="stylesheet">
<script src="static/js/bootstrap.bundle.min.js"></script>
<script src="static/js/axios.min.js"></script>
<script src="static/js/vue.global.js"></script>
<meta charset="UTF-8">
<title>应用管理</title>
</head>
<body>
<div class="container" id="app">
<h1>应用管理页面</h1>
<br/>
<div class="d-flex">
<!-- <div class="align-self-start">用户名:{{ .Username }}</div>-->
<div class="ms-auto align-self-end">
<button class="btn btn-success" @click="showModal(null)">添加应用</button>
</div>
</div>
<br/>
<table class="table">
<thead>
<tr>
<th>#</th>
<th>应用名</th>
<th>描述</th>
<th>镜像名</th>
<th>启动命令</th>
<th>环境变量</th>
<th>状态</th>
<th>服务名</th>
<th>端口</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in apps">
<td> {{ index + 1 }}</td>
<td> {{ item.AppName }}</td>
<td> {{ item.Comment }}</td>
<td> {{ item.Image }}</td>
<td> {{ item.Command }}</td>
<td> {{ item.Env }}</td>
<td> {{ item.Status }}</td>
<td> {{ item.ServiceDisplayName }}</td>
<td> {{ item.Ports }}</td>
<td>
<div class="btn-group">
<button class="btn btn-success" @click="startApp(item)">启动</button>
<button class="btn btn-dark" @click="stopApp(item)">停止</button>
<button class="btn btn-primary" @click="showModal(item)">修改</button>
<button class="btn btn-danger" @click="deleteApp(item)">删除</button>
</div>
</td>
</tr>
<tr v-if="apps.length == 0">
<td colspan="7" style="text-align: center;">点击+按钮添加应用</td>
</tr>
</tbody>
</table>
<div class="modal" tabindex="-1" id="edit-modal">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">编辑应用</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row">
<label for="app-name" class="form-label">应用名</label>
<input type="text" id="app-name" class="form-control" v-model="selectApp.AppName"
placeholder="只能为小写字母、数字和下划线"/>
</div>
<div class="row">
<label for="app-image" class="form-label">镜像</label>
<input type="text" id="app-image" class="form-control" v-model="selectApp.Image"
placeholder="Docker镜像名"/>
</div>
<div class="row">
<label for="app-cmd" class="form-label">启动命令</label>
<input type="text" id="app-cmd" class="form-control" v-model="selectApp.Command"
placeholder="启动命令,可选"/>
</div>
<div class="row">
<label for="app-env" class="form-label">环境变量</label>
<input type="text" id="app-env" class="form-control" v-model="selectApp.Env"
placeholder="环境变量,可选"/>
</div>
<div class="row">
<label for="app-svc" class="form-label">服务名</label>
<input type="text" id="app-svc" class="form-control" v-model="selectApp.SvcName"
placeholder="服务名,可选"/>
</div>
<div class="row">
<label for="app-ports" class="form-label">端口号</label>
<input type="text" id="app-ports" class="form-control" v-model="selectApp.Ports"
placeholder="端口号,多个端口以逗号分隔"/>
</div>
<div class="row">
<label for="app-comment" class="form-label">描述</label>
<textarea type="text" id="app-comment" class="form-control" v-model="selectApp.Comment"
placeholder="应用描述"></textarea>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" data-bs-dismiss="modal" @click="updateApp()">保存
</button>
</div>
</div>
</div>
</div>
<div class="position-fixed top-0 end-0 p-3" style="z-index: 11">
<div id="liveToast" class="toast alert-danger" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<strong class="me-auto">请求失败</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body">
{{ toastText }}
</div>
</div>
</div>
</div>
</body>
<script>
const {createApp} = Vue
createApp({
data() {
return {
username: "",
apps: [],
blankApp: {},
toastText: "",
selectApp: {
Id: "",
AppName: "",
UserName: "",
Image: "",
Command: "",
Comment: "",
Env: "",
SvcName: "",
Ports: "",
}
}
},
methods: {
toast(text) {
this.toastText = text
let toastLiveExample = document.getElementById('liveToast')
let toast = new bootstrap.Toast(toastLiveExample)
toast.show()
},
handleResponse(e) {
if (e.data.msg !== "ok") {
this.toast(e.data.msg)
} else {
this.refresh()
}
},
showModal(a) {
if (!a) {
a = JSON.parse(JSON.stringify(this.blankApp))
}
this.selectApp = a;
(new bootstrap.Modal("#edit-modal")).show()
},
startApp(item) {
axios.post("dep?id=" + item.Id).then(this.handleResponse)
},
deleteApp(app) {
axios.delete("app", {
data: app
}).then(this.handleResponse)
},
stopApp(app) {
axios.delete("dep?id=" + app.Id).then(this.handleResponse)
},
updateApp() {
let app = this.selectApp
if (app.Id) {
axios.put("app", app).then(this.handleResponse)
} else {
app.Id = null
app.UserName = this.username
axios.post("app", app).then(this.handleResponse);
}
},
refresh() {
axios.get("apps").then(r => {
this.username = r.data.Username
this.apps = r.data.Apps
})
}
},
mounted() {
this.blankApp = JSON.parse(JSON.stringify(this.selectApp))
this.refresh()
}
}).mount("#app")
</script>
</html>