Skip to content

Commit

Permalink
完成用户新增编辑页面,部分完成规则新增编辑页面
Browse files Browse the repository at this point in the history
  • Loading branch information
mylxsw committed Nov 3, 2019
1 parent 9bca9ad commit ff8a96d
Show file tree
Hide file tree
Showing 11 changed files with 380 additions and 3 deletions.
30 changes: 30 additions & 0 deletions api/controller/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ func (u UserController) Register(router *hades.Router) {
router.Group("/users/", func(router *hades.Router) {
router.Get("/", u.Users).Name("users:all")
router.Post("/", u.Add).Name("users:add")
router.Post("/{id}/", u.Update).Name("users:update")
router.Get("/{id}/", u.User).Name("users:one")
router.Delete("/{id}/", u.Delete).Name("users:delete")
})
Expand Down Expand Up @@ -77,6 +78,35 @@ func (u UserController) Add(ctx hades.Context, userRepo repository.UserRepo) (*r
return &user, nil
}

func (u UserController) Update(ctx hades.Context, userRepo repository.UserRepo) (*repository.User, error) {
userID, err := primitive.ObjectIDFromHex(ctx.PathVar("id"))
if err != nil {
return nil, hades.WrapJSONError(fmt.Errorf("invalid request: %v", err), http.StatusUnprocessableEntity)
}

var userForm UserForm
if err := ctx.Unmarshal(&userForm); err != nil {
return nil, hades.WrapJSONError(fmt.Errorf("invalid request: %v", err), http.StatusUnprocessableEntity)
}

ctx.Validate(userForm, true)

user, err := userRepo.Get(userID)
if err != nil {
return nil, hades.WrapJSONError(err, http.StatusNotFound)
}

user.Name = userForm.Name
user.Metas = userForm.Metas
user.Status = repository.UserStatus(userForm.Status)

if err := userRepo.Update(userID, user); err != nil {
return nil, hades.WrapJSONError(err, http.StatusInternalServerError)
}

return &user, nil
}

func (u UserController) Delete(ctx hades.Context, userRepo repository.UserRepo) error {
userID, err := primitive.ObjectIDFromHex(ctx.PathVar("id"))
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"moment": "^2.24.0",
"vue": "^2.6.10",
"vue-router": "^3.0.3",
"vue-codemirror-lite": "^1.0.4",
"vuex": "^3.0.1",
"xterm": "^4.0.1",
"xterm-addon-fit": "^0.2.1"
Expand Down
2 changes: 1 addition & 1 deletion dashboard/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<b-nav-item :to="{path:'/messages', query: {status: 'pending'}}" exact>Pending <b-badge variant="danger" v-if="pending_message_count > 0">{{ pending_message_count }}</b-badge></b-nav-item>
<b-nav-item to="/rules" exact>Rules</b-nav-item>
<b-nav-item to="/users">Users</b-nav-item>
<b-nav-item to="/queues">Queues</b-nav-item>
<b-nav-item to="/queues">Jobs</b-nav-item>
<b-nav-item to="/settings">Settings</b-nav-item>
</b-navbar-nav>
<ul class="navbar-nav flex-row ml-md-auto d-none d-md-flex">
Expand Down
6 changes: 6 additions & 0 deletions dashboard/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import Settings from "./views/Settings";
import Error from "./views/Error";
import Rules from "./views/Rules";
import Users from "./views/Users";
import UserEdit from "./views/UserEdit";
import RuleEdit from "./views/RuleEdit";

Vue.use(Router);

Expand All @@ -15,7 +17,11 @@ export default new Router({
{path: '/', component: Groups},
{path: '/messages', component: Messages},
{path: '/rules', component: Rules},
{path: '/rules/add', component: RuleEdit},
{path: '/rules/:id/edit', component: RuleEdit},
{path: '/users', component: Users},
{path: '/users/add', component: UserEdit},
{path: '/users/:id/edit', component: UserEdit},
{path: '/queues', component: Queue},
{path: '/settings', component: Settings},
{path: '/errors/', component: Error},
Expand Down
1 change: 0 additions & 1 deletion dashboard/src/views/Groups.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
<template v-slot:cell(operations)="row">
<b-button-group>
<b-button size="sm" variant="info" :to="{path:'/messages', query: {group_id: row.item.id}}">查看</b-button>
<b-button size="sm" variant="danger" >删除</b-button>
</b-button-group>
</template>
</b-table>
Expand Down
26 changes: 26 additions & 0 deletions dashboard/src/views/Queue.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
<b-spinner class="align-middle"></b-spinner>
<strong> Loading...</strong>
</template>
<template v-slot:cell(operations)="row">
<b-button-group>
<b-button size="sm" variant="danger" @click="delete_job(row.index, row.item.id)">删除</b-button>
</b-button-group>
</template>
</b-table>
<paginator :per_page="10" :cur="cur" :next="next" path="/queues" :query="this.$route.query"></paginator>
</b-col>
Expand Down Expand Up @@ -67,6 +72,27 @@
};
},
methods: {
delete_job(index, id) {
let self = this;
this.$bvModal.msgBoxConfirm('确定执行该操作 ?').then((value) => {
if (value !== true) {
return;
}
axios.delete('/api/queue/jobs/' + id + '/').then(() => {
self.jobs.splice(index, 1);
this.$bvToast.toast('操作成功', {
title: 'OK',
variant: 'success',
});
}).catch(error => {
this.$bvToast.toast(error.response !== undefined ? error.response.data.error : error.toString(), {
title: 'ERROR',
variant: 'danger'
});
});
});
},
pause_queue() {
this.$bvModal.msgBoxConfirm('确定执行该操作 ?').then((value) => {
if (value !== true) {return;}
Expand Down
157 changes: 157 additions & 0 deletions dashboard/src/views/RuleEdit.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
<template>
<b-row class="mb-5 adanos-input-box">
<b-col>
<b-form @submit="onSubmit">
<b-card-group class="mb-3">
<b-card header="基本">
<b-form-group label-cols="2" id="rule_name" label="名称*" label-for="name_input">
<b-form-input id="name_input" type="text" v-model="form.name" required
placeholder="输入规则名称"></b-form-input>
</b-form-group>

<b-form-group label-cols="2" id="rule_description" label="描述" label-for="description_input">
<b-form-textarea id="description_input" placeholder="输入规则描述"
v-model="form.description"></b-form-textarea>
</b-form-group>

<b-form-group label-cols="2" id="rule_interval" label="报警周期*" label-for="rule_interval_input"
:description="'当前:' + (parseInt(form.interval) === 0 ? 1 : form.interval) + ' 分钟,每隔 ' + (parseInt(form.interval) === 0 ? 1 : form.interval) + ' 分钟后触发一次报警'">
<b-form-input id="rule_interval_input" type="range" min="0" max="1440" step="5"
v-model="form.interval" required></b-form-input>
</b-form-group>

<b-form-group label-cols="2" id="is_enabled" label="是否启用*" label-for="is_enabled_checkbox">
<b-form-checkbox id="is_enabled_checkbox" v-model="form.status">启用</b-form-checkbox>
</b-form-group>
</b-card>
</b-card-group>

<b-card-group class="mb-3">
<b-card header="规则">
<b-form-textarea id="rule" rows="5" v-model="form.rule"
placeholder="输入规则,必须返回布尔值"></b-form-textarea>
<small class="form-text text-muted">
语法参考 <a href="https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md"
target="_blank">https://github.com/antonmedv/expr/blob/master/docs/Language-Definition.md</a>
</small>
</b-card>
</b-card-group>

<b-card-group class="mb-3">
<b-card header="模板">
<b-form-textarea id="template" rows="5" v-model="form.template"
placeholder="输入模板"></b-form-textarea>
<small class="form-text text-muted">
...
</small>
</b-card>
</b-card-group>

<b-card-group class="mb-3">
<b-card header="动作">
<b-btn variant="success" class="mb-3" @click="triggerAdd()">添加</b-btn>
<b-card class="mb-3" v-bind:key="i" v-for="(trigger, i) in form.triggers">
{{ trigger }}

<b-btn class="float-right" variant="danger" @click="triggerDelete(i)">删除</b-btn>
</b-card>
</b-card>
</b-card-group>

<b-button type="submit" variant="primary" class="mr-2">保存</b-button>
<b-button to="/rules">返回</b-button>
</b-form>
</b-col>
</b-row>
</template>

<script>
import axios from 'axios';
export default {
name: 'RuleEdit',
data() {
return {
form: {
name: '',
description: '',
interval: 1,
rule: '',
template: '',
triggers: [],
status: true,
},
properties: ['phone', 'email',]
};
},
methods: {
triggerAdd() {
this.form.triggers.push({pre_condition: '', action: '', meta: '', id: '', user_refs: []});
},
triggerDelete(index) {
this.form.triggers.splice(index, 1);
},
onSubmit(evt) {
evt.preventDefault();
let url;
if (this.$route.params.id !== undefined) {
url = '/api/rules/' + this.$route.params.id + '/';
} else {
url = '/api/rules/';
}
axios.post(url, this.createRequest()).then(() => {
this.$bvModal.msgBoxOk('操作成功', {
centered: true,
okVariant: 'success',
headerClass: 'p-2 border-bottom-0',
footerClass: 'p-2 border-top-0',
}).then(() => {
window.location.reload(true);
});
}).catch(error => {
this.$bvToast.toast(error.response !== undefined ? error.response.data.error : error.toString(), {
title: 'ERROR',
variant: 'danger'
});
});
},
createRequest() {
let requestData = {};
requestData.name = this.form.name;
requestData.description = this.form.description;
requestData.interval = this.form.interval * 60;
requestData.rule = this.form.rule;
requestData.template = this.form.template;
requestData.triggers = this.form.triggers;
requestData.status = this.form.status ? 'enabled' : 'disabled';
return requestData;
},
},
mounted() {
if (this.$route.params.id !== undefined) {
axios.get('/api/rules/' + this.$route.params.id + '/').then(response => {
this.form.name = response.data.name;
this.form.description = response.data.description;
this.form.interval = response.data.interval / 60;
this.form.rule = response.data.rule;
this.form.template = response.data.template;
this.form.triggers = response.data.triggers;
this.form.status = response.data.status === 'enabled';
}).catch(error => {
this.$bvToast.toast(error.response !== undefined ? error.response.data.error : error.toString(), {
title: 'ERROR',
variant: 'danger'
});
});
}
}
}
</script>

<style>
.adanos-input-box {
max-width: 1000px;
}
</style>
30 changes: 30 additions & 0 deletions dashboard/src/views/Rules.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<template>
<b-row class="mb-5">
<b-col>
<b-btn-group class="mb-3">
<b-button to="/rules/add" variant="primary">新增规则</b-button>
</b-btn-group>
<b-table :items="rules" :fields="fields" :busy="isBusy" show-empty>
<template v-slot:cell(name)="row">
{{ row.item.name }}
Expand All @@ -20,6 +23,12 @@
<b-spinner class="align-middle"></b-spinner>
<strong> Loading...</strong>
</template>
<template v-slot:cell(operations)="row">
<b-button-group>
<b-button size="sm" variant="info" :to="{path:'/rules/' + row.item.id + '/edit'}">编辑</b-button>
<b-button size="sm" variant="danger" @click="delete_rule(row.index, row.item.id)">删除</b-button>
</b-button-group>
</template>
</b-table>
</b-col>
</b-row>
Expand All @@ -46,6 +55,27 @@
};
},
methods: {
delete_rule(index, id) {
let self = this;
this.$bvModal.msgBoxConfirm('确定执行该操作 ?').then((value) => {
if (value !== true) {
return;
}
axios.delete('/api/rules/' + id + '/').then(() => {
self.rules.splice(index, 1);
this.$bvToast.toast('操作成功', {
title: 'OK',
variant: 'success',
});
}).catch(error => {
this.$bvToast.toast(error.response !== undefined ? error.response.data.error : error.toString(), {
title: 'ERROR',
variant: 'danger'
});
});
});
},
reload() {
axios.get('/api/rules/').then(response => {
this.rules = response.data;
Expand Down
Loading

0 comments on commit ff8a96d

Please sign in to comment.